2010-07-06 14 views
6

Ho diverse interfacce tutte con le stesse costanti: ID e ROOT. Ho anche un metodo in cui passo un oggetto che sarà un'implementazione di una di queste interfacce.Come recuperare dinamicamente una costante in java?

Come posso recuperare dinamicamente il valore della costante a seconda della classe passata - vale a dire che voglio fare qualcosa di simile al seguente:

public void indexRootNode(Node node, Class rootNodeClass) 
{ 
    indexService.index(node, rootNodeClass.getConstant('ID'), 
     rootNodeClass.getConstant('ROOT')); 
} 

In PHP questo è facile, ma è possibile questo in Java ? Ho visto questo problema risolto utilizzando gli accessor sulla costante, ma voglio recuperare direttamente la costante. Le annotazioni non mi aiuteranno neanche qui.

Grazie

+0

Date un'occhiata a riflessione – willcodejavaforfood

+1

Si prega di dare un'occhiata a questa domanda sulla memorizzazione di costanti in interfacce: http://stackoverflow.com/questions/1372991/should-a-collection-of-constants-be-placed-in-a-class-or-interface Molte persone sono d'accordo, che un'interfaccia non è una buona entità per memorizzare costanti. –

+0

Grazie, non l'avevo visto. Le interfacce che ho creato non sono raccolte di costanti. Potrei pensare di aggiungere metodi di accesso all'interfaccia, ma per brevità penso che in questo caso sia più semplice aggiungere costanti all'interfaccia. –

risposta

7

Questo può essere realizzato utilizzando reflection (vedi anche corrispondente javadoc).

public void indexRootNode(Node node, Class rootNodeClass) 
{ 
    Field idField = rootNodeClass.getField("ID"); 
    Object idValue = idField.get(null); 
    Field roorField = rootNodeClass.getField("ROOT"); 
    Object rootValue = rootField.get(null); 

    indexService.index(node, idValue, rootValue); 
} 

Forse potresti dover aggiungere i valori al tipo corrispondente.

+0

ottimo, grazie mille –

0

Si prega di leggere il capitolo 19 use interfaces only to define types da Joshua Bloch di Effective Java (in realtà, si prega di leggere l'intero libro)

costanti non appartengono in un'interfaccia !!! Le costanti dovrebbero essere legate alle classi di implementazione, non alle interfacce.

O utilizzare metodi non costanti:

// the implementing classes can define these values 
// and internally use constants if they wish to 
public interface BaseInterface{ 
    String id(); // or getId() 
    String root(); // or getRoot() 
} 

public interface MyInterface1 extends BaseInterface{ 
    void myMethodA(); 
} 

public interface MyInterface2 extends BaseInterface{ 
    void myMethodB(); 
} 

o utilizzare un enum per legare insieme le cose:

public enum Helper{ 

    ITEM1(MyInterface1.class, "foo", "bar"), 
    ITEM2(MyInterface2.class, "foo2", "baz"), 
    ; 

    public static String getId(final Class<? extends BaseInterface> clazz){ 
     return fromInterfaceClass(clazz).getId(); 

    } 

    public static String getRoot(final Class<? extends BaseInterface> clazz){ 
     return fromInterfaceClass(clazz).getRoot(); 
    } 

    private static Helper fromInterfaceClass(final Class<? extends BaseInterface> clazz){ 
     Helper result = null; 
     for(final Helper candidate : values()){ 
      if(candidate.clazz.isAssignableFrom(clazz)){ 
       result = candidate; 
      } 
     } 
     return result; 
    } 

    private final Class<? extends BaseInterface> clazz; 

    private final String root; 

    private final String id; 

    private Helper(final Class<? extends BaseInterface> clazz, 
     final String root, 
     final String id){ 
     this.clazz = clazz; 
     this.root = root; 
     this.id = id; 

    }; 

    public String getId(){ 
     return this.id; 
    } 

    public String getRoot(){ 
     return this.root; 
    } 

} 

// use it like this 
String root = Helper.fromInterfaceClass(MyInterface1.class).getRoot(); 
Problemi correlati