6

我一直将案例类的构造函数参数理解为定义公共 val。

但是,当我反映字段时,isPublic 方法出现错误。任何想法为什么?

scala> class Test( val name : String, val num : Int )
defined class Test

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> val tpe = typeOf[Test]
tpe: reflect.runtime.universe.Type = Test

scala> def checkValVisibility( t : Type ) = {
     | t.members
     |   .filter( _.isTerm )
     |   .map( _.asTerm )
     |   .filter( _.isVal )
     |   .map( memb => "Val " + memb.name.toString.trim + " is public? " + memb.isPublic )
     |   .mkString("\n")
     | }
checkValVisibility: (t: reflect.runtime.universe.Type)String

scala> checkValVisibility( tpe )
res2: String = 
Val num is public? false
Val name is public? false
4

1 回答 1

12

原因是您查询的实际值num确实name是私有的。对于案例类(和具有公共类参数的类),类参数被实现为具有公共访问器(自动为您生成)的私有字段。

如果你想使用 Scala 反射来获得一个符号,代表给定字段的公共访问器,你可以简单地做:

scala> tpe.member("name": TermName)
res02: reflect.runtime.universe.Symbol = value name

如果你这样做,你可以看到它是一个公共访问器:

scala> tpe.member("name": TermName).isPublic
res03: Boolean = true

scala> tpe.member("name": TermName).isMethod
res04: Boolean = true

在您的情况下,您过滤掉了访问者,只留下了实际的(私有)字段。您可以通过使用isAccessor(or isGetter) 而不是isVal.

scala> def checkValVisibility( t : Type ) = {
     |   t.members
     |    .filter( _.isTerm )
     |    .map( _.asTerm )
     |    .filter( _.isAccessor )
     |    .map( memb => "Val " + memb.name.toString.trim + " is public? " + memb.isPublic )
     |    .mkString("\n")
     | }
checkValVisibility: (t: reflect.runtime.universe.Type)String

scala> checkValVisibility(tpe)
res05: String = 
Val num is public? true
Val name is public? true
于 2013-03-31T16:04:39.327 回答