Scala反射在解释器和编译代码上表现不同

时间:2011-10-05 08:39:20

标签: scala reflection interpreter

我有

trait T
class C extends T

编译为.class文件。下面的代码片段加载它们:

val loader = ScalaClassLoader fromURLs (/* List[URL] */)
val classB = loader.tryToInitializeClass("B") getOrElse (/* throw something */)
println(classB.asInstanceOf[Class[_]].getInterfaces)

当我在Scala解释器中运行加载代码时,结果是

res1: Array[java.lang.Class[_]] = Array(interface T, interface scala.ScalaObject)

但是当加载代码编译成.class文件并运行时我得到了

[Ljava.lang.Class;@1b8e059

请告诉我如何使编译的加载代码产生与解释器一样好的结果。

3 个答案:

答案 0 :(得分:4)

您确定在解释的会话中执行了println吗?因为你写的第一个结果看起来很像显示just的结果的解释器 classB.asInstanceOf[Class[_]].getInterfaces),没有println(res1非常有说服力)

另一方面,神秘的[Ljava.lang.Class; @ 1b8e059是数组的toString。所以你的问题就是,toString。如果您执行println(yourResult.mkString(", "))之类的操作,那应该会更好。在REPL中,结果显示优于plain toString

答案 1 :(得分:1)

Array(interface T, interface scala.ScalaObject)[Ljava.lang.Class;@1b8e059是相同类型的对象,只是以不同的方式打印出来。

当你调用toString时,数组[类[_]]会像[Ljava.lang.Class; @ 1b8e059一样打印出来。

尝试以下方法:

scala> val f = Array[Class[_]](classOf[Map[String, String]], classOf[Object])
f: Array[java.lang.Class[_]] = Array(interface scala.collection.immutable.Map, class java.lang.Object)

scala> f.toString
res1: java.lang.String = [Ljava.lang.Class;@407e62

当打印出表达式的值时,REPL很有用。如果要在已编译的代码中打印出有用的字符串,例如:

scala> f.toList.toString
res4: String = List(interface scala.collection.immutable.Map, class java.lang.Object)

答案 2 :(得分:1)

该行

res1: Array[java.lang.Class[_]] = Array(interface T, interface scala.ScalaObject)

不是来自您的println表达式,而是来自REPL。如果输入的表达式返回除Unit之外的任何内容。 REPL打印该对象的toString方法的名称,类型和结果。

name: Type = from toString