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なんか初めからいらんかったんや!