I'm facing a weird problem with annotations in Java. When I use a static final declared array as the annotation value. I cannot access it using reflection. Why does that happens? Is it a possible bug when using static final declared arrays as parameter for Java annotations?
I'm using JDK 1.7, but I'm compiling as 1.6 using Eclipse.
As mentioned below, this code does not compile using javac, the following error occurs:
AnnotationTest.java:31: error: incompatible types: AnnotationType[] cannot be converted to AnnotationType
Here's a test code:
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])]
*/
}
}
Actually, the truth is your code does not compile with javac, but it does compile with Eclipse (at least Mars, with which I tested your code).
The error you get when compiling is:
incompatible types: AnnotationType[] cannot be converted to AnnotationType
The line:
@MyAnnotation(AnnotationType.ALL_TYPES)
does not use curly braces so Java creates for the value an array containing a single element: AnnotationType.ALL_TYPES. But since AnnotationType.ALL_TYPES is already an array, the types are no longer compatible.
This is explained in the JLS section 9.7.1:
If the element type is an array type, then it is not required to use curly braces to specify the element value of the element-value pair. If the element value is not an ElementValueArrayInitializer, then an array value whose sole element is the element value is associated with the element.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With