Отражение Scala ведет себя по-разному в интерпретаторе и скомпилированном коде - PullRequest
1 голос
/ 05 октября 2011

у меня

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 ]

4 голосов
/ 05 октября 2011

Вы уверены, что выполнили println в интерпретируемом сеансе?Поскольку первый результат, который вы пишете, выглядит подозрительно, как интерпретатор, отображающий результат просто classB.asInstanceOf[Class[_]].getInterfaces), без println (res1 очень красноречиво)

С другой стороны, загадочный [Ljava.lang.Class; @1b8e059 является строкой массива.Так что твоя проблема только в этом, toString.Если вы делаете что-то вроде println(yourResult.mkString(", ")), это должно быть намного лучше.В REPL результаты отображаются лучше, чем обычный toString

1 голос
/ 05 октября 2011

Строка

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

не исходит из вашего выражения println, она исходит из REPL.Если введенное выражение возвращает что-либо, кроме Unit.REPL печатает имя, тип и результат метода toString этого объекта.

name: Type = from toString
1 голос
/ 05 октября 2011

Array(interface T, interface scala.ScalaObject) и [Ljava.lang.Class;@1b8e059 - это один и тот же тип объекта, только распечатанный по-разному.

Массив [Class [_]] распечатывается как [Ljava.lang.Class; @ 1b8e059, когда вы вызываете toString для него.

Попробуйте следующее:

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)
...