Why don't Scala case class fields reflect as public?
scala
Solution
The reason is that the actual values that you queried for `num` and `name` are indeed private. For case classes (and classes with public class parameters), class parameters are implemented as private fields with public accessors (which are generated automatically for you).
If you want to use Scala Reflection to obtain a symbol representing the public accessor for a given field, you can simply do:
scala> tpe.member("name": TermName)
res02: reflect.runtime.universe.Symbol = value name
You can see that it's a public accessor if you do:
scala> tpe.member("name": TermName).isPublic
res03: Boolean = true
scala> tpe.member("name": TermName).isMethod
res04: Boolean = true
In your case, you filtered out the accessors, leaving only the actual (private) fields. You can change your code from above to achieve what you want by instead checking with `isAccessor` (or `isGetter`) instead of `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
Problem
I've always understood the constructor arguments of case classes as defining public vals. However, when I reflect the fields, the isPublic method comes up false. Any ideas why? ``` 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 ```