2012-07-06 64 views
2

假設我需要提供一個方法,其中包含代表某個父類A的子類的java.lang.Class對象。我需要從另一個具有綁定到A的上限類型的泛型參數的方法來完成此操作。提供使用classManifest綁定類型上限的Class對象

我想這可能工作:

class A 
def f(clazz: java.lang.Class[_ <: A]) =() 
def g[T <: A : Manifest] = f(classManifest[T].erasure) 

但事實並非如此:

<console>:9: error: type mismatch; 
found : java.lang.Class[_$1(in method g)] where type _$1(in method g) 
required: java.lang.Class[_ <: A] 
     def g[T <: A : Manifest] = f(classManifest[T].erasure) 
                ^

爲什麼不能編譯器把那塊T,着實的A一個子類?無論如何,我可以幫助它嗎?還是應該以完全不同的方式來解決這個問題?

回答

3

它不起作用,因爲erasure has the type Class[_],這是一種存在類型。這意味着Class對象erasure是通過某種類型進行參數化的,但是它的確切類型並不重要。 erasure上面沒有類型Class[T]

方法f需要Class[_ <: A]類型的參數,它是某種已知爲A的子類型的類型。這個上限不一定由上面的Class[_]類型保證。

解決方案:你知道erasure有一個正確的類型,它只是這種類型沒有在ClassManifest對象公開。只需將它轉換:

classManifest[T].erasure.asInstanceOf[Class[A]] 

編輯:

如果你有一個子類的AB

scala> class A 

scala> def f(clazz: java.lang.Class[_ <: A]) =() 

scala> def g[T <: A : Manifest] = f(classManifest[T].erasure.asInstanceOf[Class[A]]) 

scala> g[A] 

scala> class B extends A 

scala> g[B] 
+0

我接受你的答案,因爲你的解釋是正確和清晰。但是,您的解決方案對我來說不起作用,因爲我的真實世界'f'方法確實需要爲子類型提供'Class'對象,而不是'A'。我自己的解決方案是放棄使用泛型來做到這一點,並在調用路徑中傳遞類對象(通過'classOf'獲得),即調用'g'現在看起來像:'g [SomeSubclass](classOf [SomeSubclass ])'。 (由於上面未顯示的原因,類型參數仍然需要。) – 2012-07-06 16:07:54

+0

你是完全正確的。我很困惑,並沒有意識到,即使您將'B'的'Class'對象作爲'Class [A]'的一個實例'投放,它''將''''''''''''''''''''作爲'B'的'Class'對象。謝謝! – 2012-07-09 21:37:58

相關問題