如何在java中动态检索常量?

时间:2010-07-06 10:42:14

标签: java constants

我有几个接口都具有相同的常量 - ID和ROOT。我还有一个方法,我传递一个对象,这个对象将是这些接口之一的实现。

如何根据传入的类动态检索常量的值 - 即我想执行以下操作:

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

在PHP中这很简单,但这在Java中是否可行?我已经看到使用常量上的访问器解决了这个问题,但我想直接检索常量。注释也不会帮助我。

由于

2 个答案:

答案 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);
}

也许您可能需要将值转换为相应的类型。

答案 1 :(得分:0)

请阅读Joshua Bloch的use interfaces only to define types第19章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();