2010-03-27 15 views
7

Voglio usare un'annotazione in forma di compilazione sicuro.enumerazioni e annotazioni

Per passare il valore() all'annotazione, voglio utilizzare la rappresentazione String di un enum.

C'è un modo per utilizzare @A con un valore di 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(); 
} 

Aggiornamento

Ho bisogno il tipo String in @A.

Il punto è che posso fare questo

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

Ma qui rivendicazioni compilatore "valore dell'attributo deve essere costante". Is'nt E.A costante?

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

risposta

9

Il problema è che si sta più intelligenti di compilatore :-)

E.a è una costante, ma non lo è E.a.toString(). Sembra che dovrebbe essere, ma il compilatore non può capirlo.

Il motivo per cui "a"+"b" e "" + 1 funzionano è che il compilatore è abbastanza intelligente da generare le costanti in fase di compilazione.

Quando vede "" + E.a, utilizza E.a.toString(). La chiamata a toString() è sufficiente a buttarlo fuori.

E deve essere un enum? Potresti provare:

public final class E { 
    public static final String a = "a"; 
    public static final String b = "b"; 
}; 
+0

"E deve essere un enum? Potresti provare: ..." Penso che tu possa fare qualcosa di simile anche con l'enumerazione. Dovreste passare la stringa che si desidera nel costruttore per 'e', quindi assegnare a' finale String strRepresentation' pubblico. E poi basta fare '@A (E.strRepresentation)' – MatrixFrog

+0

@MatrixFrog Anche se ho messo 'finale String strRepresentation = "foo" pubblico;' su E, ottengo 'valore di attributo deve essere constant' – leedm777

7

Fai il valore nel l'annotazione di tipo E:

@interface A { 
    E value(); 
} 

quindi è possibile utilizzare

@A(E.a)