views:

132

answers:

2

I have classes

abstract class A {
    //....
}

class B extends A {
    //....
}

class C extends A {
    //....
}

Then I have

interface Maker<T extends A> {
    SomeClass make(T obj);
}

implementations for Maker class

class MakerForB implements Maker<B> { /*... */ }
class MakerForC implements Maker<C> { /*... */ }

and class Factory with one static method

class Factory {
    public static SomeClass makeSomeClass(A obj) {
        Maker maker = null;
        if(obj instanceof B) maker = new MakerForB();
        /* ... */
        return maker.make(obj);
    }
}

In that case I get warning that Maker is a raw type, when I declare Maker that way

Maker<?> maker = null;

I get exception (make is not applicable for the arguments A) on

return maker.make(obj);

What is the best way to get rid of these warnings without using

@SuppressWarnings("unchecked")
A: 

If I understand your question right, I think you could try replacing

class Factory {
    public static SomeClass makeSomeClass(A obj) {
        Maker maker = null;
        if(obj instanceof B) maker = new MakerForB();
        /* ... */
        return maker.make(obj);
    }
}

by

class Factory<S extends A> {
    public static SomeClass makeSomeClass(S obj) {
        Maker<S> maker = null;
        if(obj instanceof B) maker = new MakerForB();
        /* ... */
        return maker.make(obj);
    }
}

didn't test it, so if you get other errors now, please let me know.

Fortega
this doesn't work. the method is static. if the type S is defined on the method, it still doesn't work.
Bozho
In that case I get cannot make static reference to the non-static type S
vrm
ah yes, I see...So maybe a solution is to implement the singleton pattern in stead of using static methods?
Fortega
+5  A: 

Get rid of all generics on the Maker - you don't need it:

interface Maker {
    SomeClass make(A obj);
}

class MakerForB implements Maker {
    SomeClass make(A obj);
}

Or if you still want to use it, go with an unsafe cast or with the SuppressWarnings.

To understand why you get an error if your try defining:

Maker<? extends A> maker = null;

Imagine the case when you (by accident) get maker = new MakerForC(), and try applying it to B.

Bozho
Ok, i think I go with suppressWarnings then cause a really want to avoid casting
vrm
Marker != Maker :)
BalusC
yup. fixed that. and explained why the error appears.
Bozho