In Scala, I have an Abstract Class
:
abstract class AbstractSQLParser {
def apply(input: String): Int = {
println(reserveWords)
return 1
}
protected case class Keyword(str: String)
// use Reflection here
protected lazy val reserveWords: Int =
this.getClass
.getMethods
.filter(_.getReturnType == classOf[Keyword])
.length
}
and another extends it :
class SqlParserDemo extends AbstractSQLParser{
def apply(input: String, onError: Boolean) : Int = {
apply(input)
}
protected val CREATE = Keyword("CREATE")
protected val TEMPORARY = Keyword("TEMPORARY")
protected val TABLE = Keyword("TABLE")
protected val IF = Keyword("IF")
protected val NOT = Keyword("NOT")
protected val EXISTS = Keyword("EXISTS")
def func1 = Keyword("HI")
}
but when I call
val sqlParser = new SqlParserDemo
print(sqlParser.apply("hello", false))
the output is :
7
1
What confuses me is : why getMethods
can return the val
members ?
You see, in the sub-class, I have six val
, and one function.
In Oracle doc,
public Method[] getMethods() throws SecurityException Returns an array containing Method objects reflecting all the public member methods of the class or interface represented by this Class object, including those declared by the class or interface and those inherited from superclasses and superinterfaces
In addition to @Jorg W Mittag answer. You could compile your Scala code and then analyze resulting class with Java decompiler. For example. Here is the Scala class with sole
val
:Compile it, when decompile and you get:
So what Java reflection finds is a synthetic method generated by Scala compiler, to add such thing as
val
into JVM.Or, if you prefer to check bytecode:
See,
public int test();
method immediately after class name.Java doesn't know about
val
s.val
s are a Scala construct, not a Java construct. Ergo, Java reflection cannot return anything about aval
, because there is no such thing as aval
in Java. The closest thing to a Scalaval
in Java is a getter method, which is exactly how Scalaval
s are represented on the Java side, and which is exactly what you get when you use Java reflection instead of Scala reflection.If you use Scala reflection, you get the following: