使用静态final声明数组作为Java注释参数时可能出现的错误



我在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])]
         */
    }
}

实际上,您的代码不能用javac编译,但是可以用Eclipse(至少可以用我测试您的代码的Mars)编译。

编译时得到的错误是:

不兼容的类型:AnnotationType[]不能转换为AnnotationType

:

@MyAnnotation(AnnotationType.ALL_TYPES)

没有使用花括号,所以Java为该值创建了一个包含单个元素的数组:AnnotationType.ALL_TYPES。但是由于AnnotationType.ALL_TYPES已经是一个数组,所以类型不再兼容。

这在JLS第9.7.1节中有解释:

如果元素类型是数组类型,则不需要使用花括号指定元素-值对的元素值。如果元素值不是一个ElementValueArrayInitializer,那么一个唯一元素是元素值的数组值与元素相关联。

最新更新