I’m trying to use a Java library (JOhm) with Scala and noticed it fails when the lib tries to read the fields of my Scala classes with something like model.getClass().getDeclaredFields().
Then I decided to try to do the same with simple examples in the Scala interpreter:
scala> import java.lang.reflect.Field;
import java.lang.reflect.Field
scala> class myClass(attribute1: String, attribute2: String, attribute3: String)
defined class myClass
scala> val myInstance = new myClass("value1", "value2", "value3")
myInstance: myClass = myClass@7055c39a
scala> myInstance.getClass().getDeclaredFields()
res0: Array[java.lang.reflect.Field] = Array()
Indeed, we get no field at all.
Now, what if I try this:
scala> class myClass2(attribute1: String, attribute2: String, attribute3: String) { override def toString = this.attribute1 }
defined class myClass2
scala> val myInstance2 = new myClass2("value1", "value2", "value3")
myInstance2: myClass2 = value1
scala> myInstance2.getClass().getDeclaredFields()
res1: Array[java.lang.reflect.Field] = Array(private final java.lang.String myClass2.attribute1)
So if use one of the fields in one of the class’ methods, it is found by getDeclaredFields(). What am I missing here?
What you are missing is that constructor parameters are not automatically promoted to fields.
Rather, they are promoted only if they are used. You used
attribute1so it was turned into a field; you didn’t use the others so they were not.If you declare them as
valorvar, or the class is a case class, they will also be promoted to fields (since they will actually have accessor methods generated, and thus are used).