2013-05-26 40 views
6

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

+2

我很好奇:怎么会是怎么回事? – acdcjunior

+0

我想知道,如果我可以使用额外的注释较早的注解指定额外的参数(如@DoSomething( “F1”)@Arg( “ARG1”)@Arg( “ARG2”)@DoSomething( “F2”)@ Arg(“arg2.1”)@Arg(“arg2.2”)) – Azazar

+0

我不会这么做......看起来很混乱。普通的'@DoSomething(value =“f1”,a1 =“arg1”,a2 =“arg2”)有什么问题; @DoSomething(value =“f2”,a1 =“arg2.1”,a2 =“arg2.2”);'? – acdcjunior

回答

4

取决于你的意思是“持久性”。我认为你可能意味着问题中隐含的意思,所以这里有几个问:答:

注释顺序是否持久?
是的,它被写入.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的许多其他库。

+0

部分看起来并不可能:'验证= {@NotNull,@NotEmpty}'这是一个疏忽,或者您也可以提供'验证的定义()'成员,允许这种用法吗? –

+0

@GlennLane,你是对的。我会用更好的例子来解决。 –

1

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

+1

结帐这样的回答重复的:http://stackoverflow.com/a/30222541/810109 - 关于它的注解以**有保证的**顺序检索。 – mkurz

-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讨论。

+1

这并没有回答订单是否重要的​​问题。如果你有'public void method(@Foo @Bar String str)',假设我将它设置为处理它符合foo的所有条件的条形将会很好。你的榜样的 – corsiKa