Java 注释顺序在运行时是否持久?我检查了 OpenJDK 1.7.0_21 - 它保留了注释顺序。我可以期待所有 Java VM 上的持久性吗?
3 回答
取决于您所说的“持久”是什么意思。我认为您的意思可能暗示了问题中的某些内容,因此这里有一些问答:
注释顺序是否持久?
是的,它.class
以不变的顺序写入文件中。
文件中的注释顺序是否.class
反映了源代码中的注释顺序?
是的。如果你编译你的代码...
@Column(length = 256)
@NotBlankConstraint(message = "The application title must be set.")
@Size(min = 1, max = 256, message = "The application title must be set and not longer than 250 characters.")
private String title;
并检查javap -v
:
#67 = Utf8 Ljavax/validation/constraints/Size;
...
private java.lang.String title;
descriptor: Ljava/lang/String;
flags: ACC_PRIVATE
RuntimeVisibleAnnotations:
0: #50(#62=I#63)
1: #64(#65=s#66)
2: #67(#68=I#69,#70=I#63,#65=s#71
如果你改变注解的顺序,字节码的顺序也会改变。使用 OpenJDK 1.8.0_121 进行测试,但我认为早期的 JDK 也是如此。
该getAnnotations()
方法是否保留了来自字节码的顺序?
是的,据我所见,它始终返回与.class
文件中字节码相同的顺序。
是否getAnnotations()
保证将来反映字节码注释顺序?
不。正如另一个答案所回答的那样,这种行为没有记录在案,因此不能在公开可用的库中依赖。
但是,有一些微妙的迹象表明应该以某种方式保持订单。
现在达到您的目的,
如果可以保证,我是否应该使用命令将某些注释应用于以前的某些注释?
这是个人喜好问题,但我想说大多数 Java 程序员不喜欢这样。它不会是太多直观和可读的代码。我建议将注释分组,例如
@ValidationGroup(
validators = { @NotNull, @NotEmpty },
message = "User name must be filled."
)
public String getUsername();
这样做的问题是你不能有一个“任何注释”的数组,并且由于注释没有继承,所以不能这样做(Java 1.8)。因此,各种框架都求助于 Bean Validation 使用的东西——参见它的组概念。
最后,我要支持 Eric 的评论来检查 JSR 303,它做得很好,并且还集成到了许多其他库中,比如 RestEasy。
java.lang.reflect.AnnotatedElement.getAnnotations()
API 表示它返回此元素上存在的所有注释。它没有说明返回这些注释的顺序
在 Java 7 及更低版本中,一个元素上不能有多个相同类型的注解。您可以使它们成为另一个注释的值的一部分:
// JSR 303
@Pattern.List({
@Pattern(regexp="\\w{8,14}"),
@Pattern(regexp=".*Z.*")
})
public String getCode() {
return code;
}
Java 8 将放宽这一点。请参阅Oracle 的错误跟踪器。这在Stack Overflow 上进行了讨论。