I am playing with reflection to achieve a deep analysis on a trait. One of the things I would like to get is the initial value set to a member field. For example, in the trait:
trait A {
val x: Int = 3
val y: String = "y"
}
it would be nice to know 3 and “y”. I have not found anything related to this task in the API, and due to the following output (generated by scalac -Xprint):
abstract trait A extends Object {
<accessor> def com$hablapps$A$_setter_$x_=(x$1: Int): Unit;
<accessor> def com$hablapps$A$_setter_$y_=(x$1: String): Unit;
<stable> <accessor> def x(): Int;
<stable> <accessor> def y(): String
};
abstract trait A$class extends {
def /*A$class*/$init$($this: com.hablapps.A): Unit = {
$this.com$hablapps$A$_setter_$x_=(3);
$this.com$hablapps$A$_setter_$y_=("y");
()
}
}
I am afraid it is going to be quite hard to access them, since they are kept in the $init$ method’s body. Is there any (easy) way to get those values with reflection?
You have to disassemble the bytecode:
See line 1–the only place the value exists is in the bytecode for the init method!
You cannot get to this any other way, since if you have
you find that
CextendsA$_setter_$x_$eqto do nothing at all–making theA$class.$init$call a no-op and rendering the value unretrievable.Proof: