【问题标题】:How to process annotation and set a default value while creating object创建对象时如何处理注释并设置默认值
【发布时间】:2014-09-04 10:10:31
【问题描述】:

我想写代码,如下所示。

MyClass a = new @MyAnnotation MyClass()

假设 MyClass 方法如下所示

   public class MyClass {

    int a;

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

}

所以当有人使用注解创建 MyClass 对象时,它应该将默认值设置为某个 x(比如 20)。

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

MyClass a = new @MyAnnotation MyClass()

有谁知道我们如何在编译时将其分成两部分,如下所示?

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

或者如果我们能够像下面这样传递默认值也可以。

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

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

【问题讨论】:

  • 为什么不创建一个构造函数?你的setValue(a) 也返回Test 的类型,但在正文中,你返回了this?
  • 改成MyClass,打错字了。
  • 没有意义,它是一个实例方法,并且返回相同的实例...
  • 忽略方法返回。我的意图是在创建对象时有注释时为成员设置默认值。我尝试使用上述语法运行一些代码,但没有成功。
  • 请详细说明“但没用”。您知道类型注释功能需要 Java 8 吗?

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


【解决方案1】:

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

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

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

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

  1. 创建一个@PolyMyAnnotation 多态注解,见Polymorphic Qualifiers
  2. 为 MyClass 创建一个 PolyMorphic 构造函数,例如 @PolyMyAnnotation MyClass(@PolyMyAnnotation int a) {}
  3. 创建一个将@MyAnnotation 添加到int 文字类型的TreeAnnotator。有关示例,请参阅RegexTreeAnnotator.visitLiteral
  4. 将 TreeAnnotator 添加到 AnnotatedTypeFactory 使用的 TreeAnnotator 列表中。 (见RegexAnnotatedTypeFactory

选项 B:使用 TreeAnnotator 步骤:

  1. 创建一个扩展 TreeAnnotator 的类
  2. 覆盖 visitNewClass
  3. 确定正在构造的对象是否是 MyClass 的实例(请参阅 ElementUtils.getQualifiedClassName 和 ElementUtils.isObjectType 以了解如何执行此操作)。
  4. 如果正在构造的类是 MyClass 的实例,如果是,请查看参数是否为整数文字。
  5. 如果项目是文字,则解析文字并将其值添加到正在构造的类型中。 请注意,如果您希望它处理非文字,例如 整数a = 20; 新的 MyClass(a)

然后您可以使用 ValueChecker。如果您的类型工厂扩展了 ValueAnnotatedTypeFactory,它将支持常量传播。数据流 API 还为常量传播提供了一些支持。

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

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

【讨论】:

  • 我是批注的新手,并试图弄清楚如何实现这一点。我已经用更有意义的方式更新了这个问题。可以如您所说的那样完成还是需要使用ASM?
猜你喜欢
  • 2013-06-03
  • 2017-11-19
  • 2022-08-16
  • 2013-03-05
  • 2017-05-17
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
相关资源
最近更新 更多