Scala 为什么包对象中类型的类名包含;一揽子计划;运行时类名?
我试图生成在Scala 为什么包对象中类型的类名包含;一揽子计划;运行时类名?,scala,Scala,我试图生成在包对象中定义的类的运行时类名 例如: package com.foo package object bar { case class MyCaseClass() } import bar._ MyCaseClass().getClass.getCanonicalName 上面将生成com.foo.bar.package.MyCaseClass 如果我使用WeakTypeTag它将正确地生成类型为com.foo.bar.MyCaseClass package com.foo
包对象中定义的类的运行时类名
例如:
package com.foo
package object bar {
case class MyCaseClass()
}
import bar._
MyCaseClass().getClass.getCanonicalName
上面将生成com.foo.bar.package.MyCaseClass
如果我使用WeakTypeTag
它将正确地生成类型为com.foo.bar.MyCaseClass
package com.foo
trait MyTrait
case class MyImpl extends MyTrait
def getType[T](t: T)(implicit weakTypeTag WeakTypeTag[T]): String = {
weakTypeTag.tpe.fullName
}
上述行为差异的原因是什么?我知道我肯定遗漏了Scala类型系统的一些东西…这与其说是类型系统,不如说是JVM上包对象的编码。例如,JVM没有包级别的方法,因此Scala编译器必须创建一个合成类,该类具有与包对象中的定义相对应的静态方法、内部类等。该类名为package
,这是一个任意但自解释的名称,其优点是在Scala和Java中都是关键字,因此不太可能导致与非合成代码的冲突
Java的反射API对Scala一无所知,所以它们自然不能对您隐藏这种编码。调用getClass.getCanonicalName
时,您将看到实际的类名,与编译代码时在com/foo/bar/package\$MyCaseClass.class
中找到的类文件相对应
Scala的反射API确实知道Scala对包对象的编码,它们会对您隐藏合成的package
类。这可以说是有道理的,因为编码的细节不在规范中(如果我没记错的话?),因此可能会因平台或语言版本等而异
这种差异有点令人困惑,但这并不是唯一一次您会遇到差异Scala reflection API隐藏了许多Java reflection无法隐藏的混乱等