我有一个具有许多可设置/可获取属性的类。我想使用反射来设置这些属性,但我有两个关于我的实现的问题
以下是我班级的一些精简代码
class Q {
public String question_1;
public String question_2;
public String question_3;
public String answer_1;
public String answer_2;
public String answer_3;
//etc. etc. Many String attributes
// … constructor and other stuff are omitted
// here is my method for "dynamically" setting each attribute
public void set_attribute(String a_raw_string, String my_field) {
try {
Class cls = Class.forName("com.xyz.models.Q");
Field fld = cls.getField(my_field);
fld.set(this, a_raw_string);
}
catch (Throwable e) {
System.err.println(e);
}
}
然后我设置了各种各样的字段:
Q q = new Q();
q.set_attribute("abcde", "question_1");
q.set_attribute("defgh", "question_2");
// etc.
这是有效的(即,当我调用set_attribute时设置实例变量。
但是,它们仅在实例变量声明为public时才起作用。当它们被声明为私有时,我得到 NoSuchFieldException
问题1:为什么字段为私有时会出现错误?我天真的假设是,由于set_attribute函数是类的一部分,因此它应该可以不受限制地访问实例变量。
问题2:我想我可能会过度思考这个问题(即,我不应该使用反射以这种方式设置变量)。有更推荐的方法吗? 我想要使用反射的原因是因为宣布大量的setter方法是痛苦的...所以我想知道是否有人以更好的方式解决了这个烦恼。
谢谢!
答案 0 :(得分:1)
我想我可能正在过度思考这个问题(即,我不应该使用反射以这种方式设置变量)
是的。反思相当缓慢,只应作为最后的手段。如果这只是为了避免拥有如此多的冗余代码,请考虑使用自动代码生成。对于纯数据对象,我强烈建议使用protocol buffers;它将生成getter / setter(您只需要声明字段)。此外,它还允许在C ++,Java和Python之间轻松传递数据。
如果你的类有很多字段但不是纯数据对象......那么
通常最好将字段设置为“final”,在构造函数中初始化它们,并且不提供访问权限或通过已实现的接口提供有限的访问权限。
答案 1 :(得分:0)
使用setter方法是为类成员变量设置值的公认方法,绝对不应该使用反射,因为代码将更难理解并且运行速度要慢得多。
大多数IDE(例如Eclipse或NetBeans)都包含用于为类的字段自动创建getter和setter方法的工具。
答案 2 :(得分:0)
fld.setAccessible(true);