2010-07-06 5 views
6

J'ai plusieurs interfaces avec les mêmes constantes - ID et ROOT. J'ai aussi une méthode dans laquelle je passe un objet qui sera une implémentation de l'une de ces interfaces.Comment faire pour récupérer dynamiquement une constante dans Java?

Comment puis-je récupérer dynamiquement la valeur de la constante en fonction de la classe adoptée en - à savoir que je veux faire quelque chose comme ce qui suit:

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

En PHP cela est facile, mais est-ce possible en Java ? J'ai vu ce problème résolu en utilisant des accesseurs sur la constante, mais je veux récupérer la constante directement. Les annotations ne m'aideront pas non plus ici.

Merci

+0

Jetez un oeil à la réflexion – willcodejavaforfood

+1

S'il vous plaît jeter un oeil à cette question sur le stockage des constantes dans interfaces: http://stackoverflow.com/questions/1372991/should-a-collection-of-constants-be-placed-in-a-class-or-interface La plupart des gens sont d'accord, qu'une interface n'est pas une bonne entité pour constantes de stockage. –

+0

Merci, je n'avais pas vu ça. Les interfaces que j'ai créées ne sont pas des collections de constantes. Je pourrais penser à ajouter des méthodes d'accesseur à l'interface, mais par souci de brièveté je pense que dans ce cas il est plus simple d'ajouter des constantes à l'interface. –

Répondre

7

Ceci peut être réalisé en utilisant reflection (voir aussi correspondant 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); 
} 

Peut-être que vous devrez ajouter les valeurs au type correspondant.

+0

super, merci beaucoup –

0

S'il vous plaît lire le chapitre 19 de use interfaces only to define typesEffective Java de Joshua Bloch (en fait, s'il vous plaît lire le livre entier)

Constantes ne font pas partie d'une interface !!! Les constantes doivent être liées à des classes d'implémentation, pas à des interfaces.

Soit utiliser des méthodes non constantes:

// 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(); 
} 

ou utiliser un ENUM pour lier les choses ensemble:

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(); 
Questions connexes