我有几个接口都具有相同的常量 - ID和ROOT。我还有一个方法,我传递一个对象,这个对象将是这些接口之一的实现。
如何根据传入的类动态检索常量的值 - 即我想执行以下操作:
public void indexRootNode(Node node, Class rootNodeClass)
{
indexService.index(node, rootNodeClass.getConstant('ID'),
rootNodeClass.getConstant('ROOT'));
}
在PHP中这很简单,但这在Java中是否可行?我已经看到使用常量上的访问器解决了这个问题,但我想直接检索常量。注释也不会帮助我。
由于
答案 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();