Любой способ получить класс Java из тега или символа типа Scala (2.10)?

Похоже, это приближает меня к этому, но (а) не совсем (см. ниже) и (б) использование строкового представления имени похоже на хак...

scala> import scala.reflect.runtime.universe._import scala.reflect.runtime.universe._

scala> val t = typeOf[Int]
t: reflect.runtime.universe.Type = Int

scala> t.typeSymbol.asClass.fullName
res0: String = scala.Int

scala> object X { class Y } 
defined module X

scala> val y = typeOf[X.Y]
y: reflect.runtime.universe.Type = X.Y

scala> Class.forName(y.typeSymbol.asClass.fullName)
java.lang.ClassNotFoundException: X.Y [...]

Мне не хватает более прямого метода доступа к этой информации? Или будет лучше, если в какой-то момент мне также понадобится информация о классе, просто чтобы сохранить параллельный набор информации о классе Java? (Фу!)


person Tim    schedule 15.10.2012    source источник
comment
если вы можете получить экземпляр типа AnyRef, не можете ли вы просто вернуться к совершенству java.lang.Object-y и вызвать myObj.getClass().getName()?   -  person Steve Waldman    schedule 15.10.2012
comment
например, объект X { class Y } определяет модуль X scala› (новый XY).getClass.getName res7: java.lang.String = X$Y   -  person Steve Waldman    schedule 15.10.2012
comment
В качестве быстрого предложения попробуйте запустить scala -Xprint:typer, чтобы увидеть, действительно ли REPL оборачивает X в свои собственные объекты.   -  person pedrofurla    schedule 15.10.2012
comment
Я безуспешно пытался заставить Class.forName(package.and.object) работать в REPL.   -  person pedrofurla    schedule 15.10.2012


Ответы (2)


Получение java.lang.Class или создание экземпляров объектов с отражением должно выполняться с зеркалом, а не с типами и символами, которые являются информацией о времени компиляции для Scala:

scala> val m = runtimeMirror(getClass.getClassLoader)
m: reflect.runtime.universe.Mirror = JavaMirror with ...

scala> m.runtimeClass(typeOf[X.Y].typeSymbol.asClass)
res25: Class[_] = class X$Y
person kiritsuku    schedule 15.10.2012
comment
Он говорит только информацию о классе, не упоминая о создании экземпляра. Но все же, это, возможно, его вариант использования... - person pedrofurla; 16.10.2012
comment
Кажется, это так, если вы выбрали правильный загрузчик классов. - person Tim; 16.10.2012
comment
Функциональность ClassMirror.runtimeClass была удалена из RC1, потому что есть более короткая альтернатива: просто m.runtimeClass(typeOf[X.Y].typeSymbol.asClass). - person Eugene Burmako; 16.10.2012

Предполагая, что tag является тегом типа класса, для которого вы хотите получить класс java, вы можете сказать:

val mirror = tag.mirror
val clazz = mirror.runtimeClass(tag.tpe.typeSymbol.asClass)

В основном то же самое, что и ответ sschaef, за исключением того, что вы должны использовать зеркало непосредственно из тега вместо использования зеркала загрузчика классов текущего класса. Если текущий класс и другой класс, для которого у вас есть тег, используют разные загрузчики классов, в этом случае у вас будет ошибка загрузки класса, но не ошибка, как я объяснил.

Переменная clazz будет содержать класс java для всего, что вы пытаетесь получить.

person Angel Blanco    schedule 05.07.2015