2

My implementation of a getHandler method, which is defined on a Java interface, has failed, and I don't know why. Here is the method signature:

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

My implementation in Scala is:

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

...but the compiler gives me this message:

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

Where have I erred?

3 Answers 3

4

I think it's because your implementation doesn't uphold the contract of the interface. H could be any subtype of EventHandler, determined by the type of the aType argument. But your implementation always returns the same anonymous subtype of EventHandler, regardless of what is passed as the aType argument.

I don't know what a correct implementation would be, but I can't see how this could be implemented without somehow making use of the aType parameter.

Sign up to request clarification or add additional context in comments.

Comments

3

Adding to Lachlan's answer I'd like to point out, that simply casting the return type to the expected type may have desastrous effects.

Consider the following implementation where I have used a named class instead of the anonymous inner class from the question:

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!
  }
}

The following line will cause a ClassCastException without warning.

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

So in addition to the cast an implementation will have to ensure that the returned handler is actually assignable to H or return null or throw an exception.

Comments

1

I think this may make it compile:

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]
}

It's expecting an H. As Lachlan says, aType probably is needed somewhere.

3 Comments

...and even more succinctly: new com.google.gwt.event.shared.EventHandler() {}.asInstanceOf[H]
It might make it compile, but it is a terrible advice. The code is incorrect, and will cause problems if implemented this way.
Yes, I agree, as advice it's terrible. I looked at docjar.com/html/api/com/google/gwt/event/shared/… and decided that I was just going to answer why it does not compile. I feel bad it's the accepted answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.