我试图使用Java库(JOhm)使用Scala,发现时的lib尝试的东西,如看我的Scala类领域的失败model.getClass().getDeclaredFields()
然后,我决定尝试做同样与斯卡拉解释简单的例子:
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()
事实上,我们没有得到现场的。
现在,如果我试试这个:
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)
因此,如果使用的类的方法之一的领域之一,它是由getDeclaredFields发现()。 我缺少的是在这里吗?
你所缺少的是构造函数的参数都不会自动提升到各个领域 。
相反,只有在使用它们时就提拔。 你用attribute1
所以它变成了一个字段; 所以他们不是你没有使用其他人。
如果你声明为val
或var
或类是一个案例类,他们也将晋升为字段(因为他们实际上已经产生访问方法,因此被使用)。
如果标记字段val
或var
,然后getDeclaredFields
会发现它们,例如,
class myClass(val attribute1: String)
适用于Javadoc getFields
说,它返回“所有可访问的公共领域”,因此它是有道理的字段没有列出,除非它们被公开明确地(每默认构造函数参数私人瓦尔斯)。 然而,对于JavaDoc的getDeclaredFields
没有提到这样的限制,但领域的知名度显然这里有效果了。
编辑回应@克莱门特:
import java.lang.reflect.Field
class Foo(val a1: String, private val a2: String, a3: String, a4: String) {
val f = 10
def foo(s: String) = a4 + s
}
val foo = new Foo("v1", "v2", "v3", "v4")
foo.getClass().getDeclaredFields().foreach(println)
/* {a1, a2, a4, f} */
foo.getClass().getFields().foreach(println)
/* {} */
我的猜测是,这是因为Scala编译器不会为所有构造函数的参数字段。 如果添加var
或val
类定义字段将产生:
scala> class myClass3(val attribute1:String, attribute2:String, attribute3:String)
defined class myClass3
scala> val myInstance3 = new myClass3("value1", "value2", "value3")
myInstance: myClass3 = myClass3@fd9178
scala> myInstance3.getClass().getDecalaredFields()
res1: Array[java.lang.reflect.Field] = Array(private field java.lang.String myClass3.attribute1)
请注意,在最后两个构造函数的参数没有产生磁场。 那是因为他们仅仅是构造函数的参数,什么也不做。 当你重写了它的工作原理的原因toString
功能,我认为实际上只是因为编译器生成时的说法在被访问时使用的隐藏字段toString
方法。 我不认为这应该依靠。 你最好明确地说明构造函数的参数是你的领域。