2012-10-15 11 views
16

appare come questa mi fa vicino, ma (a) non del tutto (vedi sotto), e (b) utilizzando la rappresentazione di stringa di un nome si sente come un hack ...Un modo per ottenere una classe Java da un tag o un simbolo di 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 [...] 

Mi manca ancora un po ' metodo diretto di accesso a queste informazioni? O sarà meglio, se avrò bisogno anche delle informazioni di classe a un certo punto, solo per mantenere un insieme parallelo di informazioni sulla classe Java? (Uffa!)

+0

se è possibile ottenere un'istanza di un tipo AnyRef, non è possibile ripristinare la bontà java.lang.Object-y e chiamare myObj.getClass(). GetName()? –

+0

per esempio, oggetto X {} classe Y definito modulo X scala> (nuova XY) .getClass.getName res7: java.lang.String = X $ Y –

+0

Come un rapido suggerimento, provare a eseguire 'Scala -Xprint : typer' per vedere se e in che modo REPL sta effettivamente avvolgendo la X nei propri oggetti. – pedrofurla

risposta

23

ricezione di un java.lang.Class o dell'istanziamento degli oggetti al con la riflessione deve essere fatta con uno specchio e non con i tipi e simboli, che sono informazioni in tempo di compilazione per 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 
+0

Dice solo "informazioni sulla classe", nessuna menzione dell'istanza. Ma ancora, questo forse è il suo caso d'uso ... – pedrofurla

+0

Questo sembra farlo, a patto che tu scelga il caricatore di classi corretto. – Tim

+4

La funzionalità 'ClassMirror.runtimeClass' è stata rimossa da RC1, perché c'è un'alternativa più breve: solo' m.runtimeClass (typeOf [X.Y] .typeSymbol.asClass) '. –

4

Supponendo tag è il tag di tipo della classe che si desidera ottenere la classe java per, si può dire:

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

in sostanza la stessa risposta di sschaef, tranne che si dovrebbe usare lo specchio direttamente dal tag, invece di utilizzare lo specchio delle clas attuali s 'classloader. Se la classe corrente e l'altra classe in cui si ha il tag per utilizzare diversi programmi di caricamento di classe, si avrebbe un errore di caricamento di classe in quel caso, ma nessun errore nel modo in cui ho spiegato.

La variabile clazz manterrà la classe java per qualsiasi cosa tu stia cercando di ottenere.

Problemi correlati