简体   繁体   中英

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

I have an autogenerated Java class that I'm using in a Scala application. Something like:

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

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

I can create instances like this

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

I'd like to access the static members of this Java class. I can do it directly, like this:

Model123123.NAMES

but don't understand how to do it via reflection. I've tried:

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

and

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

I don't know a ton about Java or scala reflection, so I'm a bit lost. I'm trying to do this via reflection as I will have many classes that subclass the same parent class and I'd like to change the class dynamically at runtime.

Thanks

it should be possible like this:

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

We get the class and ask for field in a same way as we would do for non-static field. Once we have the field we can get the value of it by calling get method. The null argument means that we are not passing it any instance from which it should get the value ( since it's static member). At last we have to manually cast the type to the type we're expecting, because type information is lost at this time.

If you need to update the value of static field you can do it as

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

We again pass null since we don't need to set it on some specific instance since it's class member.

It's basically just java reflection used in the scala language. Another approach is to use scala mirrors - http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html

In your case, the best way is to cast model instance to a common interface hex.genmodel.GenModel as you did, then you can easily call getNames method to access names.

There is no need to use reflection to access static members.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM