注解无法使用常量 [Attribute value must be constant]
注解无法使用常量 [Attribute value must be constant]
because annotation and its parameters are resolved at compile time.
1 问题复现
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());public static final String BEAN_NAME = MyClass.class.getName();@Bean(name = MyClass.BEAN_NAME)
...
类似问题:
switch(param.getClass().getName()) {case String.class.getName():// to dobreak;
}
同样以下方式也会出现问题
public static final String PARAM_NAME = String.class.getName();switch(param.getClass().getName()) {case PARAM_NAME:// to dobreak;
}
2 常量表达式的定义 §15.28 Constant Expressions
15.28. Constant Expressions
A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:
- Literals of primitive type and literals of type
String
- Casts to primitive types and casts to type
String
- […] operators […]
- Parenthesized expressions whose contained expression is a constant expression.
- Simple names that refer to constant variables.
- Qualified names of the form TypeName . Identifier that refer to constant variables.
No method calls are listed there, so method call result cannot be the constant expression even if the method is trivial. But “Simple names that refer to constant variables” are listed here, so reference to the constant variable is also a constant.
A static final
field is not necessarily a compile-time constant, even if for practical purposes it’s a constant at runtime.
classObject.getName()
is a method call, and the results of method calls are by definition not compile-time constants. A string literal is a compile-time constant.
Note that while many situations could take a static final
reference as a constant for the lifetime of the program, a switch
has to have its options hard-coded at compile-time. The value of a case
target must be either an enum value or a (compile-time)
3 常量使用
常量使用有很多限制, 比如 switch-case 中, 不允许使用 MyEnum.Monday, 而只能是 Monday;
switch(enum) {case MyEnum.Monday: // 错误break;case Monday: // 正确
}
一切的原因都是因为存在 运行时 和 编译时 的区别
switch-case 很好理解, 如果存在 MyEnum.Monday 和 YouEnum.Monday, 都是常量, 但用谁的呢. 既然只能用一个类, 干脆就不让写类名了
ps: Class#getClass() 适用于具有 Class 对象但不知道实际类的代码
- 性能测试案例
- 【drag】HTML5 drag API
- matlab多元回归分析怎么计算,matlab在多元线性回归分析中的相关计算
- Linux用户权限特殊权限
- 闲话权限系统的设计
- 重启mysql
- IIS的使用
- 音频信号的数字化及压缩编码
- (笔记)yolov5自适应anchors
- ext2和ext3的主要区别
- 电脑上的准考证怎样保存电子版
- Hashtable的原理
- IDEA打包jar包,以及exe应用程序。
- R语言实现聚类kmeans
- 损失函数——均方误差(Mean Squared Error,MSE)
- Linux网络之curl命令详解
- 【CTDB】什么是CTDB(Cluster Trivial Database)