当前位置: 首页 > 面试题库 >

Java Reflection设置属性

逑阳泽
2023-03-14
问题内容

我有一个具有许多可设置/可获取的属性的类。我想使用 反射 来设置这些属性,但是我对实现有两个问题

这是我班上的一些简化代码

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之间轻松进行数据通信。

如果您有一个具有很多字段但又不是纯数据对象的类…那么

  1. 您应该考虑所有字段是否应该都是可变的。(您真的需要二传手吗?)
  2. 字段是否应该可见。(您是否需要任何访问器?)

通常,将字段设为“最终”,在构造函数中对其进行初始化,并且不提供任何访问权限或通过已实现的接口提供有限的访问权限,通常是一个好主意。



 类似资料:
  • 主要内容:Jsoup 设置属性 语法,Jsoup 设置属性 说明,Jsoup 设置属性 示例以下示例将展示在将 HTML 字符串解析为 Document 对象后使用方法设置 dom 元素的属性、批量更新和添加/删除类方法。 Jsoup 设置属性 语法 document : 文档对象代表 HTML DOM。 Jsoup : 解析给定 HTML 字符串的主类。 html : HTML 字符串。 link : 元素对象表示表示锚标记的 html 节点元素。 link.attr() : attr

  • 可查看或修改模型属性,例如,设置自定义 ID,修改模型名称、尺寸、位置等。 不同类型模型的属性设置不同,如建筑、门窗、墙等。另外,在人物/动物/植物模型属性中,设有播放动画属性。 传送点设置 编辑场景时,可以通过模型的自定义属性设置传送点。在预览场景时,第一人称行走模式下,当行走到传送点的位置时,会传送到配置的地点。 在自定义属性中添加传送属性 _Portal_,参数配置为要传送目标物体的自定义

  • 当我使用提供的Apache SOLR启动脚本(版本6.6.0)时,该脚本会创建并执行一个java命令行,该命令行具有两组SSL属性,它们的相关元素设置为相同的值。一组具有等名称,而另一组具有等名称。例如: 我们的安全团队不允许在命令行或环境变量中传递密码,但允许将它们放置在文件中,前提是该文件具有受限访问权限。我注意到在目录中有一个文件,可用于为所有属性提供默认值,包括。当我从java命令行中删除

  • 问题 在你解析一个Document之后可能想修改其中的某些属性值,然后再保存到磁盘或都输出到前台页面。 方法 可以使用属性设置方法Element.attr(String key, String value), 和Elements.attr(String key, String value). 假如你需要修改一个元素的class 属性,可以使用Element.addClass(String clas

  • 下面的示例将展示使用方法设置dom元素的属性,批量更新以及在将HTML String解析为Document对象后添加/删除类方法。 语法 (Syntax) Document document = Jsoup.parse(html); Element link = document.select("a").first(); link.attr("href","www.yahoo.c

  • 我试图在Spring Boot环境中设置一个clamav病毒扫描程序。因此,我想在属性文件clamav.properties中设置主机和端口,该文件与application.properties文件一起位于我的resources目录中。看起来是这样的: 我有这门课: 它没有连接,在日志中我得到这个: 因此,这些值显然没有设置。我做错了什么?我使用的是spring boot starter web的