5

I'm trying to create a Handler interface, which is able to handle different types of events based on their types. I'm having trouble with the following warning:

Unchecked call to 'handle(T)' as a member of raw type 'Handler'

Here are my classes.

public interface Handler<T> {
    void handle(T event); }

public class IntegerHandler implements Handler<Integer> {
    @Override
    public void handle(Integer event) {
        System.out.println("Integer: " + event);
    }
}

public class ObjectHandler implements Handler<Object> {
    @Override
    public void handle(Object event) {
        System.out.println("Object: " + event);
    }
}

public class StringHandler implements Handler<String> {
    @Override
    public void handle(String event) {
        System.out.println("String: " + event);
    }
}

public class TestHandlers {

    public static void main(String[] args) {

        String a = "hello";
        Integer b = 12;
        Long c = 23L;

        dispatch(a).handle(a);
        dispatch(b).handle(b);
        dispatch(c).handle(c);
    }

    private static Handler dispatch(Object o) {
        if (o instanceof String) {
            return new StringHandler();
        } else if (o instanceof Integer) {
            return new IntegerHandler();
        } else {
            return new ObjectHandler();
        }
    }
}

The output looks correct:

String: hello
Integer: 12
Object: 23

I guess the problem is that my dispatch method is returning a unchecked version of Handler.

Not sure what the proper way is to do this right.

scabbage
  • 1,412
  • 2
  • 15
  • 27
  • why not just call ```handle``` from the ```dispatch``` method? i.e. ```new StringHandler.handle((String) o);``` – Jorn Vernee May 28 '16 at 00:04
  • 1
    I'm not trying to fix the code, since the code works already. I'm trying to ask a design question. – scabbage May 28 '16 at 00:18
  • 3
    Did you try `dispatch(a).handle(b)`? Returning the [raw type](http://stackoverflow.com/q/2770321/2891664) `Handler` essentially makes your code non-generic. It looks like what you want is `static Handler dispatch(T o)` but that is actually difficult to make type-safe. I would suggest a change to `static Handler dispatch(Class c)` at the very least. – Radiodef May 28 '16 at 00:26
  • I actually tried to change the signature to `static Handler dispatch(T o)`. But the compiler complains `Incompatible type` because it's expecting a `Handler` when the actual returning type is a `StringHandler()`. I thought they should be the same type, right? – scabbage May 28 '16 at 00:40
  • The else object handler doesn't really allow for Handler return I think. Not sure – Aarjav May 28 '16 at 04:52
  • 1
    @Aarjav: That can be solved with `static Handler super T> dispatch(T o)`. `super` should generally be used anyway because `Handler` is a consumer. – newacct Jun 03 '16 at 05:53

1 Answers1

0

Create a factory (credit to Generic Factory With Unknown Implementation Classes)

public class HandlerFactory<H extends Handler> {

final Class<H> handlerClass;

protected HandlerFactory(final Class<H> clazz) {
    handlerClass = clazz;
}

protected H create() throws InstantiationException, IllegalAccessException {
    H handler = handlerClass.newInstance();
    return handler;
}

public static <H extends Handler> HandlerFactory<H> createFactory(final Class<H> clazz) throws InstantiationException, IllegalAccessException {
    return new HandlerFactory(clazz);
}

public static Handler dispatch(Object obj) throws InstantiationException, IllegalAccessException {
    Class c;

    if (obj instanceof String) {
        c = StringHandler.class;
    } else if (obj instanceof Integer) {
        c = IntegerHandler.class;
    } else {
        c = ObjectHandler.class;
    }
    HandlerFactory factory = HandlerFactory.createFactory(c);
    return factory.create();
}

}

Exception handlers not shown:

...
String a = "hello";
Integer b = 12;
Long c = 23L;

HandlerFactory.dispatch(a).handle(a);
HandlerFactory.dispatch(b).handle(b);
HandlerFactory.dispatch(c).handle(c);
Community
  • 1
  • 1
Tibrogargan
  • 4,508
  • 3
  • 19
  • 38