我有一个具有许多可设置/可获取的属性的类。我想使用 反射 来设置这些属性,但是我对实现有两个问题
这是我班上的一些简化代码
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方法非常麻烦……所以我想知道是否有人以更好的方式解决了这种烦恼。
谢谢!
我想我可能对此想法太想了(即,我不应该以这种方式使用反射来设置变量)
是的 反射是相当缓慢的,仅应作为最后的手段。如果只是为了避免有太多冗余代码,请考虑使用自动代码生成。对于纯数据对象,我强烈建议您使用协议缓冲区;它将生成getters / setters(您只需要声明字段)。另外,它还允许在C ++,Java和Python之间轻松进行数据通信。
如果您有一个具有很多字段但又不是纯数据对象的类…那么
通常,将字段设为“最终”,在构造函数中对其进行初始化,并且不提供任何访问权限或通过已实现的接口提供有限的访问权限,通常是一个好主意。