如何在创建对象时处理注释并设置默认值

时间:2014-09-04 10:10:32

标签: java annotations java-8 java-bytecode-asm checker-framework

我想编写代码,如下所示。

MyClass a = new @MyAnnotation MyClass()

假设MyClass方法如下所示

   public class MyClass {

    int a;

    public void setValue(int a) {
        this.a = a;
    }

}

因此,当某人使用注释创建MyClass的对象时,它应该将默认值设置为某个x(比如说20)。

在checker框架中,它允许我们在代码中注释如下。

MyClass a = new @MyAnnotation MyClass()

有没有人知道在编译时我们如何将它分成两部分?

   MyClass a = new MyClass();
   a.setValue(20);

或者如果我们能够像下面那样传递defauilt值也没关系。

MyClass a = new @MyAnnotation(value=20) MyClass()

可以使用注释处理器/需要使用像ASM这样的字节码处理器来完成它吗? 以更有意义的方式更新。

1 个答案:

答案 0 :(得分:1)

您是否通过元注释编写自定义类型系统?也就是说,您使用的是SubtypingChecker,还是您创建了自己的BaseTypeChecker子类型?

简短的回答是,使用元注释,您无法指定此类行为。答案很长,如果你有一个自定义检查器,那么有很多方法可以做到这一点。

但请记住,编写自定义检查程序比使用元注释要复杂得多。但是,如果您有自定义检查程序,则可以执行以下操作之一:

选项A:多态构造函数 步骤进行:

  1. 创建@PolyMyAnnotation多态注释,请参阅Polymorphic Qualifiers
  2. 为MyClass创建一个PolyMorphic构造函数,例如: @PolyMyAnnotation MyClass(@PolyMyAnnotation int a){}
  3. 创建一个TreeAnnotator,将@MyAnnotation添加到int literals的类型中。有关示例,请参阅RegexTreeAnnotator.visitLiteral
  4. 将TreeAnnotator添加到AnnotatedTypeFactory使用的TreeAnnotators列表中。 (见RegexAnnotatedTypeFactory
  5. 选项B:使用TreeAnnotator 步骤进行:

    1. 创建一个扩展TreeAnnotator
    2. 的类
    3. 覆盖visitNewClass
    4. 确定正在构造的对象是否是MyClass的实例(请参阅ElementUtils.getQualifiedClassName和ElementUtils.isObjectType以了解如何执行此操作)。
    5. 如果正在构造的类是MyClass的实例,如果是,请查看参数是否为Integer文字。
    6. 如果项目是文字,则解析文字并将其值添加到正在构造的类型中。 请注意,如果您希望这样处理非文字,例如 int a = 20; 新的MyClass(a)
    7. 然后您可以使用ValueChecker。如果您的类型工厂扩展了ValueAnnotatedTypeFactory,它将支持常量传播。数据流API还为常量传播提供了一些支持。

      选项C:自定义数据流的CFAbstractTransfer功能 但是,如果您有自定义检查器,则可以覆盖CFAbstractTransfer.visitMethodInvocation以检测何时调用setValue并相应地对其进行优化。您可以查看RegexTransfer示例,或搜索扩展CFAbstractTransfer或实现TransferFunction的方法。

      也就是说,数据流不能替代类型状态系统(参见Typestate checkers的讨论)。