【问题标题】:How do I access a Java static member from Scala with reflection?如何通过反射从 Scala 访问 Java 静态成员?
【发布时间】:2016-04-28 15:26:38
【问题描述】:

我有一个在 Scala 应用程序中使用的自动生成的 Java 类。比如:

public class Model123123 extends GenModel {
  public int nclasses() { return 4; }

  // Names of columns used by model.
  public static final String[] NAMES = NamesHolder_Model123123.VALUES;

我可以创建这样的实例

val model = Class
          .forName("Model123123")
          .newInstance()
          .asInstanceOf[GenModel]

我想访问这个 Java 类的静态成员。我可以直接做,像这样:

Model123123.NAMES

但不明白如何通过反射来做到这一点。我试过了:

scala> Class.forName("Model123123").NAMES
<console>:10: error: value NAMES is not a member of Class[?0]
              Class.forName(model_name).NAMES

scala> model.getClass.NAMES
<console>:11: error: value NAMES is not a member of Class[?0]
              model.getClass.NAMES

我不太了解 Java 或 scala 反射,所以我有点迷茫。我试图通过反射来做到这一点,因为我将有许多类继承同一个父类,并且我想在运行时动态更改类。

谢谢

【问题讨论】:

    标签: java scala reflection h2o


    【解决方案1】:

    应该是这样的:

    val clazz = Class.forName("Model123123")
    val field = clazz.getDeclaredField("NAMES")
    val value = field.get(null).asInstanceOf[Array[String]]
    

    我们获取类并请求字段的方式与我们为非静态字段所做的方式相同。一旦我们有了这个字段,我们就可以通过调用get 方法来获取它的值。 null 参数意味着我们没有向它传递任何它应该从中获取值的实例(因为它是静态成员)。最后我们必须手动将类型转换为我们期望的类型,因为此时类型信息丢失了。

    如果你需要更新静态字段的值,你可以这样做

    field.set(null, Array[String]("name1", "name2"))
    

    我们再次传递 null 因为我们不需要在某些特定实例上设置它,因为它是类成员。

    它基本上只是 scala 语言中使用的 java 反射。另一种方法是使用 scala 镜像 - http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html

    【讨论】:

    • 谢谢,效果很好!不知道 getDeclaredField
    【解决方案2】:

    在您的情况下,最好的方法是像您一样将模型实例转换为公共接口hex.genmodel.GenModel,然后您可以轻松调用getNames 方法来访问名称。

    不需要使用反射来访问静态成员。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-15
      • 2016-02-16
      • 2011-12-15
      • 1970-01-01
      • 2016-01-13
      • 1970-01-01
      • 2018-10-05
      相关资源
      最近更新 更多