2010-09-01 169 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或抛出异常。