【问题标题】:Why cannot all statements be annotated in Java?为什么不能在 Java 中注释所有语句?
【发布时间】:2012-06-14 10:16:52
【问题描述】:

我天真地尝试这样做时遇到了一个简单的问题:

public void someMethod(){    
  int x = 0;
  ...
  @SuppressWarnings({"rawtypes", "unchecked"})
  x = ((Comparable)lhs).compareTo(rhs);
  ...
}

这是非法的,必须改写才能编译:

public void someMethod(){  
  ...  
  @SuppressWarnings({"rawtypes", "unchecked"})
  int x = ((Comparable)lhs).compareTo(rhs);
  ...
}

我已将问题追溯到ElementType:语句似乎不是有效的程序元素。这相当令人困惑——我认为语句类似于所有编程元素的超类型。

  1. 是否存在限制有效元素的理论或技术原因?

  2. 能否以不同的方式完成 - 即假设我可以用自己的班级取代 ElementType 并掌握涟漪变化,我可以注释任何声明吗?

【问题讨论】:

  • 完全不清楚这里的上下文是什么。您实际上没有指定注释并没有帮助。真的,你想做什么?
  • 我试图做并且已经做的是抑制一些编译器警告。我现在要做的是了解我不能注释随机语句的更深层次的原因。我对编程语言的理论不是很擅长,但是这个看似随意的限制让我很感兴趣
  • 所以请展示完整的上下文。您是要在方法中执行此操作,还是声明实例变量等?
  • @Jon 我试图在一个方法中做到这一点,注释一个局部变量。已相应地编辑了问题。
  • 对。编辑使这一点更加清晰,尽管缩进也会有所帮助......

标签: java annotations element


【解决方案1】:

如果您查看the Javadoc for @SuppressWarnings,您会看到答案:它声明的目标是

@Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})

换句话说,它不能合法地应用于语句。但是,它可以应用于变量声明。它与语句是否是程序元素无关;基本上是因为这个注解只适用于事物的声明。

此外,如果您查看 the Javadoc for the enumeration that describes things that can have annotations, 语句和表达式,则不在选择之列。一般来说,注释可以应用于事物的声明,而不是代码。

这样做的理论上的原因只是注释被存储为类文件中声明的单个项目的属性。陈述不合格;当你的代码被编译时,语句已经不存在了。只有一个字节码流,它来自的语句的唯一提醒是(可选的)行号表。为了解决这个问题,他们需要在类文件中添加一个新属性来引用各个字节码,如this proposal, 并处理由此产生的许多复杂性。

【讨论】:

  • 谢谢你,欧内斯特。我知道规范。该问题已经有指向 ElementType 的链接。我想知道,为什么决定将注释限制在声明中。
  • 作为 JSR-308 专家组的前成员,我不得不对包含几个无效陈述和主要作者自己的猜测的最后一段投反对票,尤其是围绕“仅行号”部分。跨度>
  • 嘿嘿。您必须删除所有带有“唯一”一词的陈述以使其可信。 :)
【解决方案2】:

我知道一个答案已经被接受,只是把它扔在那里。以下是 JSR-175 的常见问题解答的摘录,它最初为 Java 添加了注释:

为什么不能注释任意程序元素,例如块和单个语句?

这会使注释语法大大复杂化:我们不得不牺牲说注释只是修饰符的简单性,可以在声明中使用。

换句话说,因为工作量太大:-)

【讨论】:

  • 不错的一个,让我重新考虑接受的答案,因为这个答案来自马的嘴。谢谢
【解决方案3】:

has been proposed 作为JSR-308 的一部分允许对语句进行注释,但目前不支持并且不会成为下一个 Java 语言版本(即 Java 8)的一部分。

我猜在语言中添加注释时,主要目标类和方法级别的信息主要围绕运行时用例(例如 Java EE、JPA、JAX-WS 等)制作,而语句级别的注释主要在编译时有用(有关用例列表,请参阅上面的 wiki 链接)。

【讨论】:

  • 感谢您的参考,尤金。那么期待JSR-308 :)
【解决方案4】:

Java 中的声明是具有标识符的实体,可以从程序的其他部分引用。语句不符合该标准 - 它是一个可能导致将值分配给某个声明的实体的操作。

Java 规范 (http://docs.oracle.com/javase/specs/jls/se5.0/html/names.html#6.1) 的第 6.1 节列出了声明的类型,与 ElementType 枚举值一致。

【讨论】:

  • 谢谢,亚历克斯。第二句话让我更清楚一点——一个陈述不能被引用。位为什么在这里引用很重要?该语句在语法树中占有一席之地,可以通过遍历到达,因此可以通过其他方式访问...
  • @kostja 不确定。也许这与注释经常在运行时用于通过反射获取有关程序元素的信息这一事实有关。据我所知,没有办法使用反射来访问程序中的语句。
猜你喜欢
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-01
  • 1970-01-01
  • 2010-12-10
相关资源
最近更新 更多