2010-07-06 16 views
6

Tengo varias interfaces todas con las mismas constantes: ID y ROOT. También tengo un método en el que paso un objeto que será una implementación de una de estas interfaces.¿Cómo recuperar dinámicamente una constante en Java?

¿Cómo puedo dinámicamente recuperar el valor de la constante que depende de la clase aprobada en - es decir, lo que quiero hacer algo como lo siguiente:

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

En PHP esto es fácil, pero es posible esto en Java ? He visto este problema resuelto usando accessors en la constante, pero quiero recuperar la constante directamente. Las anotaciones no me ayudarán aquí tampoco.

Gracias

+0

Tome un vistazo a la reflexión – willcodejavaforfood

+1

favor, eche un vistazo a esta pregunta sobre el almacenamiento de las constantes en interfaces: http://stackoverflow.com/questions/1372991/should-a-collection-of-constants-be-placed-in-a-class-or-interface La mayoría de las personas está de acuerdo en que una interfaz no es una buena entidad para constantes de tienda –

+0

Gracias, no había visto eso. Las interfaces que he creado no son colecciones de constantes. Pude pensar en agregar métodos de acceso a la interfaz, pero por brevedad creo que en este caso es más simple agregar constantes a la interfaz. –

Respuesta

7

Esto puede lograrse usando reflection (véase también la correspondiente 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); 
} 

Quizás también tenga que convertir los valores en el tipo correspondiente.

+0

genial, muchas gracias –

0

Por favor, lea el capítulo 19 use interfaces only to define types de Joshua Bloch Effective Java (de hecho, por favor leer el libro entero)

Constantes no tienen cabida en una interfaz !!! Las constantes deben vincularse a las clases de implementación, no a las interfaces.

O bien utilizar métodos no 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(); 
} 

o utilizar una enumeración para atar cosas juntas:

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(); 
Cuestiones relacionadas