2012-10-15 8 views
16

Wygląda na to dostaje mnie blisko, ale (a) nie do końca (patrz poniżej), oraz (b) przy użyciu znaków reprezentujący nazwę czuje hack ...Jakikolwiek sposób uzyskania klasy Java ze znacznika lub symbolu typu 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 [...] 

jestem brakuje niektórych więcej bezpośrednia metoda dostępu do tych informacji? A może najlepiej będzie, jeśli w jakimś momencie będę potrzebował informacji o klasie, aby zachować równoległy zestaw informacji o klasie Java? (Fuj!)

+0

jeśli możesz uzyskać instancję typu AnyRef, czy nie możesz po prostu powrócić do właściwości java.lang.Object-y i wywołać myObj.getClass(). GetName()? –

+0

na przykład obiekt klasy X {Y} zdefiniowany moduł X scala> (nowa XY) .getClass.getName res7: java.lang.String = X $ Y –

+0

Jako szybki sugestia, spróbuj uruchomić 'scala -Xprint : typer', aby zobaczyć, czy i jak REPL faktycznie opakowuje X w swoje własne obiekty. – pedrofurla

Odpowiedz

23

Odbieranie java.lang.Class lub instancji obiektów z odbicia muszą być wykonane z lustrem, a nie z rodzaju i symboli, które są kompilacji informacji o czasie do 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

Mówi tylko "informacje o klasie", bez wzmianki o instancji. Ale nadal, to może być jego przypadek użycia ... – pedrofurla

+0

Wygląda na to, że tak, o ile wybierzesz prawidłowy program ładujący klasy. – Tim

+4

Funkcja 'ClassMirror.runtimeClass' została usunięta z RC1, ponieważ istnieje krótsza alternatywa: po prostu' m.runtimeClass (typeOf [X.Y] .typeSymbol.asClass) '. –

4

Zakładając tag jest tag typ klasy chcesz dostać klasy javy, możesz powiedzieć:

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

zasadniczo taka sama jak odpowiedź sschaef, z wyjątkiem należy użyć lustra bezpośrednio ze znacznika, zamiast używania lustro bieżących clas s 'classloader. Jeśli obecna klasa i inna klasa, do której masz znacznik, używają różnych programów ładujących klasy, to w takim przypadku wystąpiłby błąd ładowania klas, ale nie wyjaśniono żadnego błędu.

Zmienna clazz przechowuje klasę Java dla wszystkiego, co próbujesz uzyskać.

Powiązane problemy