Da Li
Da Li

Reputation: 319

How to get the type of a field using reflection?

Is there a way to get the Type of a field with scala reflection?

Let's see the standard reflection example:

scala> class C { val x = 2; var y = 3 }
defined class C
scala> val m = ru.runtimeMirror(getClass.getClassLoader)
m: scala.reflect.runtime.universe.Mirror = JavaMirror ...
scala> val im = m.reflect(new C)
im: scala.reflect.runtime.universe.InstanceMirror = instance mirror for C@5f0c8ac1
scala> val fieldX = ru.typeOf[C].declaration(ru.newTermName("x")).asTerm.accessed.asTerm
fieldX: scala.reflect.runtime.universe.TermSymbol = value x
scala> val fmX = im.reflectField(fieldX)
fmX: scala.reflect.runtime.universe.FieldMirror = field mirror for C.x (bound to C@5f0c8ac1)
scala> fmX.get
res0: Any = 2

Is there a way to do something like

val test: Int = fmX.get

That means can I "cast" the result of a reflection get to the actual type of the field? And otherwise: is it possible to do a reflection set from a string? In the example something like

fmx.set("10")  

Thanks for hints!

Upvotes: 0

Views: 531

Answers (1)

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297155

Here's the deal... the type is not known at compile time, so, basically, you have to tell the compiler what the type it's supposed to be. You can do it safely or not, like this:

val test: Int = fmX.get.asInstanceOf[Int]

val test: Int = fmX.get match {
  case n: Int => n
  case _      => 0 // or however you want to handle the exception
}

Note that, since you declared test to be Int, you have to assign an Int to it. And even if you kept test as Any, at some point you have to pick a type for it, and it is always going to be something static -- as in, in the source code.

The second case just uses pattern matching to ensure you have the right type.

I'm not sure I understand what you mean by the second case.

Upvotes: 2

Related Questions