Есть класс B наследующийся от класса A:
class A(val aparam: String) {...}
class B(bparam: String) extends A(bparam) {
var someb1 = "somevalue"
val someb2 = "somevalue"
}
Если с помощью reflection исследовать класс B:
val b = new B("hello")
val mirror = runtimeMirror(b.getClass.getClassLoader)
val alltypes = mirror.reflect(b).symbol.typeSignature.baseClasses.filter(c => c.isClass).map(c => c.asClass.typeSignature)
val vars: Seq[TermSymbol] = alltypes.flatMap(t => t.members.filter(m => m.isTerm && (m.asTerm.isVal || m.asTerm.isVar)).map(x => x.asTerm))
И вывести «vars», то выдастся что-то вида:
value aparam
value bparam
variable someb1
value someb2
Т.е. выдаются и аргументы первичного конструктора (bparam)
Вопрос: Как различить аргументы первичного конструктора от «полей», т.е.
хочется игнорировать
bparam и не игнорировать
aparam (метод isParamAccessor
выдаст true для aparam и bparam)?
Если в дальнейшем попытаться получить значение bparam через reflection
(например так: vars.map(v => mirror.reflect(b).reflectField(v).get), то выпадет исключение:
scala.ScalaReflectionException: Scala field aparam isn't represented as a Java
field, neither it has a Java accessor method note that private parameters of
class constructors don't get mapped onto fields and/or accessors, unless they
are used outside of their declaring constructors.
О котором и предупреждают в scaladoc к reflectField:
If a field symbol doesn't correspond to a reflectable entity of the underlying
platform, a ScalaReflectionException exception will be thrown. This might
happen, for example, for primary constructor parameters. Typically they produce
class fields, however, private parameters that aren't used outside the
constructor remain plain parameters of a constructor method of the class.