如何使用反射从 Scala 访问 Java 静态成员?

How do I access a Java static member from Scala with reflection?

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

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 class 的静态成员。我可以直接做,像这样:

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 反射,所以我有点迷茫。我正在尝试通过反射来做到这一点,因为我将有许多 class 子 class 同一个父 class 并且我想动态地更改 class运行。

谢谢

应该可以这样:

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

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

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

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

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

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

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

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