下面的代码定义了一个特征T
,其中包含私有val someVal
和一个扩展T
的匿名类。如果我们从匿名类的实例中调用getMethods
,someVal
将被列为公共方法:
scala> trait T { private val someVal = 3 }
defined trait T
scala> new T {}.getClass.getMethods.apply(0)
res2: java.lang.reflect.Method = public int $anon$1.$line6$$read$T$$someVal()
当然{@ 1}}在这个子类中是不可访问的,但为什么它甚至在someVal
的公共回报中呢?
答案 0 :(得分:3)
trait
编译为interfaces
,因为它们需要多重继承。但是接口既没有字段也没有非public
成员。因此,字段成为一对public
访问器,由特征名称修改,编译器的任务是将字段放入所有子类并实现访问器。尝试访问T
的{{1}}上的任何方法都会通过getter,而someVal
static
函数(包含构造函数代码)会使用setter将其设置为{{ 1}}。如果您的$init$
被声明为3
,那么获取者的名称将被解除为val
,外部代码将使用该名称,如果它也是public
, setter将解除someVal
,然后变为var
。无论如何,可怕的长名称足以阻止任何人使用它们,并且它只与Java互操作有关。