2010-09-01 165 views
2

我在一個Java接口上定義的getHandler方法的實現失敗,我不知道爲什麼。下面是該方法的簽名:在Scala中實現Java接口方法

<H extends EventHandler> H getHandler(Type<H> type, int index); 

我在Scala實現是:

def getHandler[H <: com.google.gwt.event.shared.EventHandler] 
    (aType: Type[H], index: Int): H 
    = new com.google.gwt.event.shared.EventHandler() {} 

...但編譯器給了我這個消息:

type mismatch; 
    found: java.lang.Object with com.google.gwt.event.shared.EventHandler 
    required: H 

我在哪裏犯了錯誤?

回答

1

我想,這可能使編譯:

def getHandler[H <: com.google.gwt.event.shared.EventHandler] 
    (aType: Type[H], index: Int): H = { 
    val h = new com.google.gwt.event.shared.EventHandler() {} 
    h.asInstanceOf[H] 
} 

該公司預計的H。正如Lachlan所說,aType可能需要某處。

+0

...甚至更簡潔: 新的com.google.gwt.event.shared.EventHandler(){} .asInstanceOf [H] – David 2010-09-01 03:10:12

+0

它可能會使它編譯,但它是一個可怕的建議。代碼不正確,如果以這種方式實施,將會導致問題。 – 2010-09-01 14:17:51

+1

是的,我同意,作爲建議它是可怕的。我查看了http://www.docjar.com/html/api/com/google/gwt/event/shared/HandlerManager.java.html,並決定我只是回答爲什麼它不能編譯。我感到不好,這是公認的答案。 – huynhjl 2010-09-02 01:18:49

4

我認爲這是因爲你的實現不支持接口的合同。 H可能是的任何子類型EventHandler,由aType參數的類型決定。但是您的實現總是返回與EventHandler相同的匿名子類型,而不管通過了什麼作爲aType參數。

我不知道什麼是正確的實現,但我不明白如何在不使用aType參數的情況下實現這個功能。

3

加入Lachlan's answer我想指出的是,簡單地將返回類型轉換爲預期類型可能會造成災難性後果。

考慮下面的執行,我已經從這個問題中使用的匿名內部類的命名類,而不是:

class MyHandlerA extends EventHandler 
class MyHandlerB extends EventHandler 

object BadImplementation extends I { 
    def getHandler[H <: EventHandler](typ : Type[H], index: Int) = { 
    (new MyHandlerA).asInstanceOf[H] // BAD: This asInstanceOf is a lie! 
    } 
} 

下面一行將導致ClassCastException沒有警告。

val b: MyHandlerB = BadImplementation.getHandler(new Type[MyHandlerB] {} , 0) 

所以除了劇組的實現必須確保返回的句柄實際上是分配到H或返回null或拋出異常。