2010-07-06 2 views
6

У меня есть несколько интерфейсов с одинаковыми константами - ID и ROOT. У меня также есть метод, в который я передаю объект, который будет реализацией одного из этих интерфейсов.Как динамически извлекать константу в java?

Как динамически получить значение константы в зависимости от класса принят в - то есть я хочу сделать что-то вроде следующего:

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

В PHP это легко, но это возможно в Java ? Я видел, что эта проблема решена с помощью accessors на константе, но я хочу получить константу напрямую. Аннотации мне тоже не помогут.

Благодаря

+0

Посмотрите на отражение – willcodejavaforfood

+1

Пожалуйста, обратите внимание на этот вопрос о хранении константы интерфейсы: http://stackoverflow.com/questions/1372991/should-a-collection-of-constants-be-placed-in-a-class-or-interface Большинство людей согласны с тем, что интерфейс не является хорошим объектом для постоянные хранилища. –

+0

Спасибо, я этого не видел. Созданные интерфейсы не являются наборами констант. Я мог подумать о добавлении методов доступа к интерфейсу, но для краткости я думаю, что в этом случае проще добавить константы в интерфейс. –

ответ

7

Это может быть достигнуто с помощью reflection (смотрите также соответствующие 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); 
} 

Возможно, вам может потребоваться присвоить значения соответствующему типу.

+0

отлично, спасибо большое –

0

Пожалуйста, прочтите главу 19 use interfaces only to define types от Джошуа Блоха Effective Java (на самом деле, пожалуйста, прочитайте всю книгу)

Константы не принадлежат в интерфейсе !!! Константы должны быть привязаны к реализации классов, а не к интерфейсам.

Либо использовать непостоянные методы:

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

или использовать перечисление, чтобы связать все вместе:

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(); 
Смежные вопросы