我对Java还是很陌生,所以我很难解释我要做什么。
我有一个抽象类,它调用了几个这样的对象常量:
public abstract class Enchantment implements Keyed {
/**
* Provides protection against environmental damage
*/
public static final Enchantment PROTECTION_ENVIRONMENTAL = new EnchantmentWrapper("protection");
在另一个文件中,我可以使用
Enchantment value = Enchantment.PROTECTION_ENVIRONMENTAL;
但是,我正尝试为此使用字符串变量。像这样:
String str = "PROTECTION_ENVIRONMENTAL";
Enchantment value = Enchantment.str;
显然那是行不通的。因此,我进行了大量研究,并了解到需要对此进行反思。使用此源代码的文档,我认为我正在寻找字段数据。所以我都尝试了:
Field fld = Enchantment.class.getField("PROTECTION_ENVIRONMENTAL");
Field fld = Enchantment.class.getDeclaredField("PROTECTION_ENVIRONMENTAL");
但是这些返回了我NoSuchFieldException。在进行此操作时,我同样尝试了getMethod()
和getDeclaredMethod()
,但都没有碰运气。
我现在说的是这些可能是“对象常量”?我不确定如何称呼他们。但是我绝对不知道如何使它现在开始工作,在尝试了所有方法之后,我认为是时候在这里寻求帮助了。
答案 0 :(得分:3)
如果您知道枚举将是常量值,则可能需要调查一下;
public enum Enchantment {
PROTECTION_ENVIRONMENTAL {
public void cast() {
// do enum-specific stuff here
}
},
ANOTHER_ENCHANTMENT {
public void cast() {
// do enum-specific stuff here
}
},
A_THIRD_ENCHANTMENT{
public void cast() {
// do enum-specific stuff here
}
};
public abstract void cast();
}
枚举可以像类一样对待,并具有方法和属性。您还可以在字符串Enchantment.valueOf("PROTECTION_ENVIRONMENTAL")
之间来回转换,但这通常是在从配置文件中读取时-在代码中直接引用该值。
答案 1 :(得分:3)
上面有一个评论:您绝对在这里不要使用反射。
使用反射只有两个有效的理由:
但是您的代码完全了解该Enchantment类,其功能等等。因此,反射是错误的方法。您自己想像得出:该死的很难做对,而该死的正确做错了一些微妙的方式。当您弄错了它时,它总是在运行时崩溃。反射代码 compiling 毫无意义。它总是在等待您运行它以吐在您的脸上。
因此通过不回答来回答您的问题:使用地图。喜欢:
Map<String, Enchantment> enchantmentsByConstantName = new HashMap<>();
enchantmentsByConstantName.put("PROTECTION_ENVIRONMENTAL", PROTECTION_ENVIRONMENTAL);
或者,如其他答案所述,这些常量也可以放入一个枚举中,但方式明显不同:
enum EnchantmentHolder {
PROTECTION_ENVIRONMENTAL(new EnchantmentWrapper("protection")),
ANOTHER_ENCHANTMENT(...)
A_THIRD_ENCHANTMENT(...)
...;
private Enchantment enchantment;
private EnchantmentHolder(Enchantment enchantment) {
this.entchantment = entchantment;
}
public Enchantment getEntchantment() { return entchantment; }
答案 2 :(得分:2)
拥有Field
后,您需要使用实例(在这种情况下为class
)调用Field.get(Object)
。像
Class<?> cls = Enchantment.class;
try {
Field f = cls.getField("PROTECTION_ENVIRONMENTAL");
System.out.println(f.get(cls));
} catch (Exception e) {
e.printStackTrace();
}
由于您需要Enchantment
,因此 可以 ,然后测试所获得的实例是否可分配给Enchantment
。像
Class<? extends Enchantment> cls = Enchantment.class;
try {
Field f = cls.getField("PROTECTION_ENVIRONMENTAL");
Object obj = f.get(cls);
if (cls.isAssignableFrom(obj.getClass())) {
Enchantment e = cls.cast(obj);
System.out.println(e);
}
} catch (Exception e) {
e.printStackTrace();
}
但是enum
方法更好。