Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot use getDeclaredFields() to retrieve fields of a Scala class

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?

like image 581
Clément Avatar asked Aug 07 '12 19:08

Clément


People also ask

How do I access a private string?

If we want to access Private Field and method using Reflection we just need to call setAccessible(true) on the field or method object which you want to access. Class. getDeclaredField(String fieldName) or Class. getDeclaredFields() can be used to get private fields.

What is the difference between getField and getDeclaredField?

getField method returns only public members whereas getDeclaredField method returns members with any access modifier. Also, getField can get a field inherited from a superclass - getDeclaredField can't. It's the same for the other methods which start with "getDeclared-".

What is getField?

getFields() returns an array containing Field objects reflecting all the accessible public fields of the class or interface represented by this Class object. The method returns an array of length 0 if the class or interface has no accessible public fields, or if it represents an array class, a primitive type, or void.


1 Answers

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 attribute1 so it was turned into a field; you didn't use the others so they were not.

If you declare them as val or var, 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).

like image 193
Rex Kerr Avatar answered Sep 28 '22 09:09

Rex Kerr