Как динамически получить константу в Java? - PullRequest
6 голосов
/ 06 июля 2010

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

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

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

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

Спасибо

Ответы [ 2 ]

7 голосов
/ 06 июля 2010

Этого можно добиться, используя отражение (см. Также 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 голосов
/ 06 июля 2010

Пожалуйста, прочитайте главу 19 Используйте интерфейсы только для определения типов из Эффективной 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();
...