我总是将case类的构造函数参数理解为定义公共值。
但是,当我反映字段时,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
答案 0 :(得分:12)
原因是您查询num
和name
的实际值确实是私有的。对于案例类(以及具有公共类参数的类),类参数实现为具有公共访问器的私有字段(为您自动生成)。
如果您想使用Scala Reflection获取代表给定字段的公共访问者的符号,您只需执行以下操作:
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
(或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