我在Java中面临一个奇怪的注释问题。当我使用static final
声明的数组作为注释值时。我无法使用反射访问它。为什么会这样?使用静态最终声明的数组作为Java注释的参数时,这是一个可能的错误吗?
我使用的是JDK 1.7,但我使用Eclipse编译为1.6。
如下所述,此代码不使用javac进行编译,发生以下错误:
AnnotationTest.java:31: error: incompatible types: AnnotationType[] cannot be converted to AnnotationType
这是一个测试代码:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.Arrays;
enum AnnotationType {
TYPE_ONE, TYPE_TWO;
public static final AnnotationType[] ALL_TYPES = { TYPE_ONE, TYPE_TWO };
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MyAnnotation {
AnnotationType[] value();
}
public class AnnotationTest {
@MyAnnotation(AnnotationType.TYPE_ONE)
public void methodTypeOne() {
}
@MyAnnotation(AnnotationType.TYPE_TWO)
public void methodTypeTwo() {
}
// This annotation does not show up.
@MyAnnotation(AnnotationType.ALL_TYPES)
public void methodAllTypes() {
}
// This one shows up fine.
@MyAnnotation({ AnnotationType.TYPE_ONE, AnnotationType.TYPE_TWO })
public void methodAllSingleTypes() {
}
public static void main(String[] args) throws Exception {
Class<?> clazz = AnnotationTest.class;
for (Method m : clazz.getDeclaredMethods())
// Doesn't work for getDeclaredAnnotations() as well.
System.out.println(m.getName() + " -> " + Arrays.toString(m.getAnnotations()));
// This is what's printed.
/*
main -> []
methodTypeOne -> [@annotation.test.MyAnnotation(value=[TYPE_ONE])]
methodTypeTwo -> [@annotation.test.MyAnnotation(value=[TYPE_TWO])]
methodAllTypes -> []
methodAllSingleTypes -> [@annotation.test.MyAnnotation(value=[TYPE_ONE, TYPE_TWO])]
*/
}
}
答案 0 :(得分:2)
实际上,事实上你的代码不使用javac进行编译,但它确实用Eclipse编译(至少是Mars,我测试了你的代码)。
编译时遇到的错误是:
不兼容的类型:AnnotationType []无法转换为AnnotationType
该行:
@MyAnnotation(AnnotationType.ALL_TYPES)
不使用花括号,因此Java为值创建一个包含单个元素的数组:AnnotationType.ALL_TYPES
。但由于AnnotationType.ALL_TYPES
已经是一个数组,因此类型不再兼容。
这在JLS section 9.7.1中解释:
如果元素类型是数组类型,则不需要使用花括号来指定元素值对的元素值。如果元素值不是ElementValueArrayInitializer,则其唯一元素是元素值的数组值与元素相关联。