Как динамично получить константу в Java?

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

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

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

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

Спасибо

6
задан Michael Jones 6 July 2010 в 10:42
поделиться

2 ответа

Этого можно достичь, используя 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);
}

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

7
ответ дан 17 December 2019 в 00:02
поделиться

Прочтите главу 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();
0
ответ дан 17 December 2019 в 00:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: