7

Java 注释顺序在运行时是否持久?我检查了 OpenJDK 1.7.0_21 - 它保留了注释顺序。我可以期待所有 Java VM 上的持久性吗?

4

3 回答 3

6

取决于您所说的“持久”是什么意思。我认为您的意思可能暗示了问题中的某些内容,因此这里有一些问答:

注释顺序是否持久?
是的,它.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。

于 2017-02-09T00:36:19.410 回答
2

java.lang.reflect.AnnotatedElement.getAnnotations()API 表示它返回此元素上存在的所有注释。它没有说明返回这些注释的顺序

于 2013-05-26T04:56:05.673 回答
-5

在 Java 7 及更低版本中,一个元素上不能有多个相同类型的注解。您可以使它们成为另一个注释的值的一部分:

// JSR 303
@Pattern.List({
    @Pattern(regexp="\\w{8,14}"),
    @Pattern(regexp=".*Z.*")
})
public String getCode() {
    return code;
}

Java 8 将放宽这一点。请参阅Oracle 的错误跟踪器。这在Stack Overflow 上进行了讨论。

于 2013-05-26T05:14:20.670 回答