当前位置: 首页 > 面试题库 >

需要Java中的默认构造函数?

韦胜泫
2023-03-14
问题内容

除了* 使用如下所示的反射检查 之外 ,是否有任何方法 要求
类具有默认(无参数)构造函数?(以下方法可以工作,但是很hacky,反射速度很慢)
*

 boolean valid = false;
 for(Constructor<?> c : TParse.class.getConstructors())
 {
   if(c.getParameterTypes().length == 0) {
      valid = true;
      break; 
   }
 }
 if(!valid)
    throw new MissingDefaultConstructorException(...);

问题答案:

您可以为此构建一个注释处理器。注释处理器是在编译时运行的编译器插件。它们的错误显示为编译器错误,甚至可能停止构建。

这是一个示例代码(尽管我没有运行它):

@SupportedAnnotationTypes("*")   // needed to run on all classes being compiled
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class DefaultConstructor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations,
            RoundEnvironment roundEnv) {

        for (TypeElement type : ElementFilter.typesIn(roundEnv.getRootElements())) {
            if (requiresDefaultConstructor(type))
                checkForDefaultConstructor(type);
        }
        return false;
    }

    private void checkForDefaultConstructor(TypeElement type) {
        for (ExecutableElement cons :
            ElementFilter.constructorsIn(type.getEnclosedElements())) {
            if (cons.getParameters().isEmpty())
                return;
        }

        // Couldn't find any default constructor here
        processingEnv.getMessager().printMessage(
                Diagnostic.Kind.ERROR, "type is missing a default constructor",
                type);
    }

    private boolean requiresDefaultConstructor(TypeElement type) {
        // sample: require any JPA Entity to have a default constructor
        return type.getAnnotation(Entity.class)) != null
               || type.getQualifiedName().toString().contains("POJO");
    }

}

如果引入注释(例如RequiresDefaultAnnotation),则注释处理器将变得更加容易。

声明具有默认限定符的要求

::我还假设OP要求一种机制来防止开发人员意外错误,尤其是其他人编写的错误。

必须有一种机制来声明哪些类需要默认处理器。希望您已经有了相应的条件,无论是名称中的模式,限定符中的模式,可能的注释和/或基本类型。在上面提供的示例中,您可以在方法中指定条件requiresDefaultConstructor()。这是一个如何完成的示例:

  1. 基于名称模式。 TypeElement提供对完全限定名称和程序包名称的访问。

    return type.getQualifiedName().toString().contains("POJO");
    
  2. 基于类型声明上存在的注释。例如,所有Java Bean Entity类都应具有非默认构造函数

    return type.getAnnotation(Entity.class) != null;
    
  3. 基于抽象类或接口。

    TypeElement basetype = processingEnv.getElements().getTypeElement("com.notnoop.mybase");
    

    return processingEnv.getTypes().isSubtype(type.asType(), basetype.asType());

  4. [推荐方法]:如果使用的是基本类型接口,建议将注释方法与基本类型接口混合使用。您可以声明一个注释,例如MyPlain和元注释:@Inherited。然后,您可以使用该批注对基本类型进行批注,然后所有子类也将继承该批注。然后你的方法就是

    return type.getAnnotation(MyPlain.class) != null;
    

如果模式确实基于类型层次结构并且您拥有根类,那么这样做会更好一些,因为它更具可配置性。

如前所述,仅仅因为它被称为“注释处理”,就意味着您必须使用注释!您要遵循列表中的哪种方法取决于您的上下文。基本上,关键是要在部署实施工具中配置的任何逻辑都可以使用requiresDefaultConstructor

处理器将运行的类

对任何给定类的注释处理器调用都取决于SupportedAnnotationTypes。如果SupportedAnnotationTypes元注释指定了具体的注释,则处理器将仅在包含此类注释的那些类上运行。

如果SupportedAnnotationTypes"*",则将在所有带注释的类上调用处理器!查看[Javadoc](http://java.sun.com/javase/6/docs/api/javax/annotation/processing/Processor.html#getSupportedAnnotationTypes()),其中指出:

最后,"*"它本身代表所有注释类型的集合,包括空集合。请注意,"*"除非处理器实际上正在处理所有文件,否则不应声明。声称不必要的注释可能会导致某些环境下的性能下降。

请注意如何false返回以确保处理器不声明所有注释。



 类似资料:
  • 问题内容: 我知道我在这里问一些严重的101问题… 我有一些课,还有一个延伸课。在我有一个构造函数,它接受一组参数,并对其字段进行设置。派生类(例如)通常不需要进行修改。现在我的IDE给我 “ Foo中没有默认的构造函数” 。从一点点谷歌搜索,这似乎是因为“构造函数没有继承”。因此,一切都很好,但是我现在如何使它工作而不在每个派生类中复制此构造函数?我假设有一个更合理的方法? 问题答案: 使用构造

  • 问题内容: 当未定义构造函数时,它工作正常,但如果我定义了一个参数化的构造函数而不是默认的构造函数, 并且在创建对象时未传递任何值, 则会出错。我认为构造函数是预定义的。 如果定义了参数化构造函数,为什么需要定义默认构造函数?默认构造函数不是预定义的吗? 问题答案: 仅 当您自己未定义任何构造函数时, 才会 自动创建默认(无参数)构造函数。 如果需要两个构造函数,一个带有参数,另一个不带参数,则需

  • 问题内容: 默认构造函数到底是什么?你能告诉我以下哪个是默认构造函数,它与其他构造函数有何不同? 问题答案: 他们都不是。如果定义,则不是默认值。 除非你定义另一个构造函数,否则默认构造函数是自动生成的无参数构造函数。任何未初始化的字段都将设置为其默认值。对于你的榜样,它看起来像这样假设的类型String,int以及int,那类本身是公共的: 这与 完全没有构造函数。但是,如果定义至少一个构造函数

  • 我知道,如果类实现了外部化,它应该有无参数的构造函数,但是如果类没有任何构造函数(就像我的类),java会为它提供空的无参数的构造函数。那为什么我有个错误呢?如果将无参数构造函数()显式添加到类,则一切都将正常。 错误: 线程“main”java.io.InvalidClassException中的异常:a;java.base/java.io.ObjectStreamClass$Exception

  • 实际上,我不明白无参数构造函数和默认构造函数的区别是什么。 在创建名为cFrame的Test对象时,是否调用此类的默认构造函数?

  • 我有如下三节课 二等 调用父类方法的最后一个类 PS:帖子标题可能有误。如果是错的,我会根据答案修改。