2012-07-25 62 views
2

是否可以使用新的反射庫顯示保存在字節碼中的完整類型簽名(帶有已擦除參數化類型)?反射:顯示靜態類型的字節碼類型簽名

例如因爲這是存儲在字節碼的類型的類型

Any => Unit 

應顯示爲

"scala.Function1<java.lang.Object,scala.runtime.BoxedUnit>" 

。可以用javap來顯示此類型。第一個需要編寫一些代碼scalac

object X { 
    def m(f: Any => Unit) = f 
} 

命令javap -c -s -l -verbose X$顯示:

... 
const #25 = Asciz (Lscala/Function1<Ljava/lang/Object;Lscala/runtime/BoxedUnit;>;)Lscala/Function1<Ljava/lang/Object;Lscala/runtime/BoxedUnit;>;; 
... 
public scala.Function1 m(scala.Function1); 
    Signature: (Lscala/Function1;)Lscala/Function1; 
... 

javap輸出是有點不可思議,我更感興趣的是獲得的「Java一樣」輸出。也許一個表示類型簽名的字符串可能更容易產生這個字符串。

又如:

package abc 
object O { 
    def x(i: Int)(j: Int) = i+j 
} 

// type of x should be displayed something like 
"int abc.O$.x(int, int)" 

是這樣的已經支持,如果不是如何建立任何類型的這樣的輸出?

回答

0

類型已經是完整類型簽名,但它們不包含完整路徑。爲此,你必須去符號,並得到它的主人,或類似的東西。

每一個關於新思考的問題都是這樣做的,所以如果你可以更具體一些,這將有所幫助。

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

scala> typeOf[abc.O.type].member(newTermName("x")).typeSignatureIn(typeOf[abc.O.type]) 
res0: reflect.runtime.universe.Type = (i: scala.Int)(j: scala.Int)scala.Int 
+0

我對類型簽名的字符串表示感興趣,因爲它保存在字節碼中。在您的代碼示例中,例如多參數列表應該只顯示爲一個參數列表,因爲JVM字節碼中不存在多個參數列表。 – sschaef 2012-07-26 10:30:41

+0

@sschaef然後你的問題沒有意義。字節碼簽名被擦除,所以'Any => Unit'就是'Function1'。 – 2012-07-26 13:18:52

+0

簽名不會被刪除(不完全)。 javap爲'Any => Unit'顯示簽名'Lscala/Function1 '。 – sschaef 2012-07-26 14:23:41