如何在java中动态获取常量?

e0bqpujr  于 2023-01-11  发布在  Java
关注(0)|答案(2)|浏览(257)

我有几个接口,它们都有相同的常量-- ID和ROOT。我还有一个方法,我向其中传递一个对象,该对象将是这些接口之一的实现。
如何根据传入的类动态检索常量的值--也就是说,我想做类似以下的事情:

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

在PHP中这很容易,但是在Java中这可能吗?我看到这个问题通过在常量上使用访问器来解决,但是我想直接检索常量。注解在这里也帮不了我。
谢谢

piv4azn7

piv4azn71#

这可以使用reflection实现(另请参见相应的javadoc)。

public void indexRootNode(Node node, Class rootNodeClass)
{
    Field idField = rootNodeClass.getField("ID");
    Object idValue = idField.get(null);
    Field rootField = rootNodeClass.getField("ROOT");
    Object rootValue = rootField.get(null);

    indexService.index(node, idValue, rootValue);
}

也许您还必须将值强制转换为相应的类型。

of1yzvn4

of1yzvn42#

请阅读约书亚Bloch的Effective Java中的第19章useinterfaces only to defined type(实际上,请阅读整本书)
常量不属于接口!!!常量应该绑定到实现类,而不是接口。
使用非常量方法:

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

相关问题