2012-10-15 76 views
16

看起來這讓我接近,但(一)不完全(見下文),和(b)使用名稱的字符串表示感覺就像一個黑客...從Scala(2.10)類型標記或符號獲取Java類的任何方式?

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類信息? (唉!)

+0

如果你可以得到一個AnyRef類型的實例,你不能只返回到java.lang.Object-y的好處,並調用myObj.getClass()。getName()? –

+0

例如,對象X {類Y} 定義模塊X 階>(新XY).getClass.getName res7:java.lang.String中= X $ Y –

+0

作爲快速建議,嘗試運行'階-Xprint :typer「來查看REPL是否以及如何將X包裝到自己的對象中。 – pedrofurla

回答

23

接聽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 
+0

他只說「班級信息」,沒有提到實例化。但是,這仍然可能是他的用例... – pedrofurla

+0

只要你碰巧選擇了正確的類加載器,似乎這樣做。 – Tim

+4

'ClassMirror.runtimeClass'功能已從RC1中刪除,因爲有一個較短的選擇:只是'm.runtimeClass(typeOf [X.Y] .typeSymbol.asClass)'。 –

4

假設tag是類型標籤你想獲得的Java類爲類的,你可以說:

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

基本上一樣sschaef的答案,但你應該從標籤直接使用,而不是使用當前CLAS的鏡子鏡子, s'classloader。如果當前類和其他具有標籤的類使用不同的類加載器,那麼在這種情況下您將遇到類加載錯誤,但是我解釋的方式沒有錯誤。

clazz變量將爲您想要獲得的任何東西保存java類。