views:

119

answers:

2

I want to use an Annotation in compile-safe form.

To pass the value() to the Annotation i want to use the String representation of an enum.

Is there a way to use @A with a value from enum E ?

public class T {

    public enum E {
        a,b;
    }

    // C1: i want this, but it won't compile
    @A(E.a)
    void bar() {

    // C2: no chance, it won't compile
    @A(E.a.toString())
    void bar2() {

    }
    // C3: this is ok
    @A("a"+"b")
    void bar3() {

    }

    // C4: is constant like C3, is'nt it ?
    @A(""+E.a)
    void bar4() {

    }
}

@interface A {
    String value();
}

Update

I need the String type in @A.

The point is i can do this

@A("" + 1)
    void foo() {
}

But here the compiler claims "attribute value must be constant". Is'nt E.a constant ?

@A("" + E.a)
    void foo() {
}
+3  A: 

Make the value in the annotation of type E:

@interface A {
   E value();
}

Then you can use

@A(E.a)
Yardena
+1  A: 

The problem is that you're smarter than the compiler :-)

E.a is a constant, but E.a.toString() is not. It looks like it should be, but the compiler can't figure that out.

The reason why "a"+"b" and "" + 1 work is that the compiler is smart enough to generate the constants at compile time.

When it sees "" + E.a, it uses E.a.toString(). The call to toString() is enough to throw it off.

Does E have to be an enum? You could try:

public final class E {
  public static final String a = "a";
  public static final String b = "b";
};
dave
"Does E have to be an enum? You could try: ..." I think you can do something similar with enums too. You'd have to pass in the String that you want in the constructor for `E`, then assign it to `public final String strRepresentation`. And then just do `@A(E.strRepresentation)`
MatrixFrog
@MatrixFrog Even if I put `public final String strRepresentation = "foo";` on E, I get `attribute value must be constant`
dave