Java注释顺序是否持久?

时间:2013-05-26 04:43:10

标签: java reflection annotations

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

3 个答案:

答案 0 :(得分:5)

取决于你的意思"执着"。我想你可能在这个问题中暗示了一些隐含的东西,所以这里有一些Q& A:

注释顺序是否持久?
是的,它是以.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()保证将来会反映字节码注释顺序吗?
不会。正如另一个答案所回答的那样,这种行为没有记录,因此无法在公共图书馆中使用。
但是,某种程度上有subtle signs that the order should be kept

现在达到你的目的, 如果有保证,我是否应该使用该订单将某些注释应用于之前的某些注释?
这是一个品味问题,但我想说大多数Java程序员都不会这样。它不会是非常直观和可读的代码。我建议将注释分组如

@ValidationGroup(
     validators = { @NotNull, @NotEmpty },
     message = "User name must be filled."
)
public String getUsername(); 

这个问题是你不能有一个"任何注释"的数组,并且由于注释没有继承,所以不能这样做( Java 1.8)。所以各种框架都采用了Bean Validation使用的方法 - 参见它的群组概念。

最后,我在Eric的评论中排在第二位,检查JSR 303,它做得很好,并且还集成到RestEasy等许多其他库中。

答案 1 :(得分:1)

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

答案 2 :(得分:-4)

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

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

Java 8将放松这一点。见Oracle's bug tracker。这在Stack Overflow讨论过。