getDeclaredFieldsとtrait
case classのフィールドをリフレクションで取得するときの話。
以下REPLで
scala> case class A(a: String, b: Int) defined class A scala> val a = classOf[A] a: java.lang.Class[A] = class A scala> a.getDeclaredFields res0: Array[java.lang.reflect.Field] = Array(private final java.lang.String A.a, private final int A.b)
フィールドを持つtraitを継承させたcase classだと、traitのフィールドも含まれてしまう。。
(試してないからわかんないけど、Javaのinterface定数でもこうなるのかな?)
scala> trait Base{
| var base1: String = _
| var base2: String = _
| }
defined trait Base
scala> case class B(a: String, b: Int) extends Base
defined class B
scala> val b = classOf[B]
b: java.lang.Class[B] = class B
scala> b.getDeclaredFields
res1: Array[java.lang.reflect.Field] = Array(private final java.lang.String B.a, private final int B.b, private java.lang.String B.base1, private java.lang.String B.base2)
仕方ないからabstract classを使うことにした。
scala> abstract class AbstractBase{
| var base1: String = _
| var base2: String = _
| }
defined class AbstractBase
scala> case class C(a: String, b: Int) extends AbstractBase
defined class C
scala> val c = classOf[C]
c: java.lang.Class[C] = class C
scala> c.getDeclaredFields
res2: Array[java.lang.reflect.Field] = Array(private final java.lang.String C.a, private final int C.b)
それにしてもREPLは補完が効くし大変素晴らしい。
IDEなんか初めからいらんかったんや!