注释属性必须是类文字?为什么?常数也应该没问题 [英] Annotation attribute must be a class literal? Why? Constants should be fine too

查看:1735
本文介绍了注释属性必须是类文字?为什么?常数也应该没问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以解释为什么String和Class注释参数的预期不同吗?为什么编译器需要Classes的文字,wherby也接受字符串的常量?

Can someone explain why String and Class annotation parameters are expected differently? Why does the compiler require literals for Classes, wherby accepting constants for Strings as well?

Spring的@RequestMapping工作示例:

Working example with Spring's @RequestMapping:

public class MyController {
    public static final String REQUEST_MAPPING = "/index.html";
    @RequestMapping(MyController.REQUEST_MAPPING) // ALL OK!
    ...
}

使用TestNG的@Test的WTF示例:

WTF example with TestNG's @Test:

public class MyControllerTest {
    public static final Class TEST_EXCEPTION = RuntimeException.class;
    @Test(expectedExceptions = MyControllerTest.TEST_EXCEPTION) // compilation error, WTF:
    // The value for annotation attribute Test.expectedExceptions must be a class literal
    ...
}

当然有什么工作是@Test(expectedExceptions = RuntimeException.class)。但为什么?我看到的注释参数的唯一区别是它的类型:String vs Class。为什么Java编译器也会接受String常量,但只接受类文字?

What does work of course is @Test(expectedExceptions = RuntimeException.class). But why? The only difference in the annotation parameter I see is its type: String vs Class. Why on earth would the Java compiler accept String constant as well but accept only class literals?

推荐答案

Java语言规范没有允许您使用参数类型为 Class 的编译时常量。你只能使用类文字。

The Java Language Specification doesn't permit you to use compile-time constants with parameters of type Class. You can only use class literals.

JLS 有关于合适的注释参数值的说明:

The JLS has the following to say about suitable parameter values for annotations:


当且仅当满足下列条件之一时,元素类型 T 与元素值 V 相称:


  • T 是一个数组类型 E [] ,并且:

    • V ElementValueArrayInitializer V 中的每个 ElementValueInitializer (类似于数组初始值设定项中的变量初始值设定项)与相当>电子。或者

    • V 是一个与 T 相称的 ElementValue

    • T is an array type E[] and either:
      • V is an ElementValueArrayInitializer and each ElementValueInitializer (analogous to a variable initializer in an array initializer) in V is commensurate with E. Or
      • V is an ElementValue that is commensurate with T.

      • 如果 T 是基本类型或字符串, V 是一个常量表达式(§15.28)

      • V 不为空。

      • 如果 T 是Class,或者是Class的调用,而V是类文字(§15.8.2)

      • 如果 T 是枚举类型, V 是枚举常量。

      • If T is a primitive type or String, V is a constant expression (§15.28).
      • V is not null.
      • if T is Class, or an invocation of Class, and V is a class literal (§15.8.2).
      • If T is an enum type, and V is an enum constant.

      如果元素类型与之不相称,则为编译时错误 ElementValue

      It is a compile-time error if the element type is not commensurate with the ElementValue.

      然而,我不能说为什么这个限制在JLS中。

      I can't say why this restriction is in the JLS, however.

      这篇关于注释属性必须是类文字?为什么?常数也应该没问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆