views:

501

answers:

2

I would like to use constants for annotation values.

interface Client {

    @Retention(RUNTIME)
    @Target(METHOD)
    @interface SomeAnnotation { String[] values(); }

    interface Info {
     String A = "a";
     String B = "b";
     String[] AB = new String[] { A, B };
    }

    @SomeAnnotation(values = { Info.A, Info.B })
    void works();

    @SomeAnnotation(values = Info.AB)
    void doesNotWork();
}

The constants Info.A and Info.B can be used in the annotation but not the array Info.AB as it has to be an array initializer in this place. Annotation values are restricted to values that could be inlined into the byte code of a class. This is not possible for the array constant as it has to be constructed when Info is loaded. Is there a workaround for this problem?

+2  A: 

Why not make the annotation values an enum, which are keys to the actual data values you want?

e.g.

enum InfoKeys
{
 A("a"),
 B("b"),
 AB(new String[] { "a", "b" }),

 InfoKeys(Object data) { this.data = data; }
 private Object data;
}

@SomeAnnotation (values = InfoKeys.AB)

This could be improved for type safety, but you get the idea.

amarillion
+1 Nice thinking. An example that compiled would have been even nicer ;-)
skaffman
Good idea. This is okay if you're able to change the annotation. You have to use @interface SomeAnnotation { InfoKeys values(); }. Sadly, it cannot change the annotation type itself.
Thomas Jung
Changing the annotation type would restrict the use to values of this enumeration. This is to retrictive for most use cases.
Thomas Jung
@Thomas: yes, this approach also has disadvantages. It really depends on what you want to achieve exactly.
amarillion
You have an given annotation. The use of this annotation should be not redundant. The ideal solution would be to support full and partial reuse of an "annotation instance". Full reuse: @x = @SomeAnnotation(...); @x m(); @x y();. Partial reuse: @SomeAnnotation(childAnnotation=@x) m(). Referencing annotation values is a compromise not a goal.
Thomas Jung
+2  A: 

No, there is no workaround.

Thomas Jung