Scala 反射:为什么 getMethods 可以返回 val 成员? [英] Scala Reflection : why getMethods can return the val members?

查看:50
本文介绍了Scala 反射:为什么 getMethods 可以返回 val 成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Scala 中,我有一个 抽象类:

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
}

另一个扩展它:

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")
}

但是当我打电话

val sqlParser = new SqlParserDemo
print(sqlParser.apply("hello", false))

输出是:

7

1

让我困惑的是:为什么 getMethods 可以返回 val 成员?

What confuses me is : why getMethods can return the val members ?

你看,在子类中,我有六个 val一个函数.

You see, in the sub-class, I have six val , and one function.

在 Oracle 文档中,

In Oracle doc,

公共方法[] getMethods()throws SecurityException 返回一个包含 Method 对象的数组,这些对象反映了所有公共成员方法这个 Class 对象所代表的类或接口,包括由类或接口声明的和继承自的超类和超接口

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

推荐答案

Java 不知道 vals.vals 是 Scala 构造,而不是 Java 构造.因此,Java 反射无法返回任何关于 val 的信息,因为 Java 中没有 val 这样的东西.Java 中最接近 Scala val 的是 getter 方法,这正是 Scala val 在 Java 端的表示方式,这正是您在您使用 Java 反射而不是 Scala 反射.

Java doesn't know about vals. vals are a Scala construct, not a Java construct. Ergo, Java reflection cannot return anything about a val, because there is no such thing as a val in Java. The closest thing to a Scala val in Java is a getter method, which is exactly how Scala vals are represented on the Java side, and which is exactly what you get when you use Java reflection instead of Scala reflection.

如果你使用 Scala 反射,你会得到以下结果:

If you use Scala reflection, you get the following:

import scala.reflect.runtime.{universe => ru}

def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]

val theType = getTypeTag(sqlParser).tpe
theType.declarations
// => reflect.runtime.universe.MemberScope = 
//      SynchronizedOps(
//        constructor SqlParserDemo, 
//        value CREATE, 
//        value CREATE, 
//        value TEMPORARY, 
//        value TEMPORARY, 
//        value TABLE, 
//        value TABLE, 
//        value IF, 
//        value IF, 
//        value NOT, 
//        value NOT, 
//        value EXISTS, 
//        value EXISTS, 
//        method func1)

这篇关于Scala 反射:为什么 getMethods 可以返回 val 成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆