Invalid Java Override Return Type

I have a project that has the following components:

public abstract class BaseThing {
    public abstract <T extends BaseThing> ThingDoer<T, String> getThingDoer();
}

public class SomeThing extends BaseThing {
    public ThingDoer<SomeThing, String> getThingDoer() {
        return Things.getSomeThingDoer();
    }
}

public class SomeOtherThing extends BaseThing {
    public ThingDoer<SomeOtherThing, String> getThingDoer() {
        return Things.getSomeOtherThingDoer();
    }
}

public class Things {
    public ThingDoer<SomeThing, String> getSomeThingDoer {
        return getThingDoer(SomeThing.class);
    }

    public ThingDoer<SomeOtherThing, String> getSomeOtherThingDoer {
        return getThingDoer(SomeOtherThing.class);
    }

    private <D extends ThingDoer<T, String> D getThingDoer(Class<T> clazz) {
        //get ThingDoer
    }
}

public class ThingDoer<T, V> {
    public void do(T thing) {
        //do thing
    }
}

public class DoThing {
    private BaseThing thing;

    public void doIt() {
        thing.getThingDoer().do(thing);
    }
}

I get a compiler warning SomeThing.getThingDoer()in which says:

Uncontrolled redefinition: return type requires unchecked conversion.

Found ThingDoer<SomeThing, String>, requiredThingDoer<T, String>

Everthing compiles fine, and as long as I haven’t been able to check DoThing.doIt(), I have no reason to believe that this will not work.

My question is: can this gap and is there a better way to do this? I could make a DoThingbase class and have subclasses for SomeThingand SomeOtherThing, but that doesn't look very elegant.

EDIT: I would like to avoid creating BaseThinggeneric.

+3
1

BaseThing , :

public abstract class BaseThing {
    public abstract <T extends BaseThing> ThingDoer<T, String> getThingDoer();
}

, . , <T> . : public <T> Class<T> classOf(T object). . , - "" generic ( ), , Collections: public <T> List<T> emptyList(). , <T> ; , emptyList() , . - T, .

. BaseThing:

public class SomeThing extends BaseThing {
    public ThingDoer<SomeThing, String> getThingDoer() {
        return Things.getSomeThingDoer();
    }
}

public class SomeOtherThing extends BaseThing {
    public ThingDoer<SomeOtherThing, String> getThingDoer() {
        return Things.getSomeOtherThingDoer();
    }
}

abstract . Java , . , , Number , Integer , Integer Number.

a List<Integer> a List<Number>. , ThingDoer<T, String> ( T extends BaseThing), , ThingDoer<SomeThing, String> ThingDoer<SomeOtherThing, String>, T, SomeThing SomeOtherThing BaseThing.

( API) , T, . , ( , ) .

: "" ( ) :

public abstract ThingDoer<? extends BaseThing, String> getThingDoer();

, ThingDoer , -, BaseThing ( , BaseThing), API.

№ 2. ...

OP:

BaseThing thing = /* ... */;
thing.getThingDoer().do(thing);

, thing , getThingDoer(). , getThingDoer(), thing ( OP). .

API BaseThing ThingDoer . API :

thing.doTheThing();

:

public class SomeThing extends BaseThing {
    @Override public void doTheThing() {
        Things.getSomeThingDoer().do(this);
    }
}

public class SomeOtherThing extends BaseThing {
    @Override public void doTheThing() {
        Things.getSomeOtherThingDoer().do(this);
    }
}
+6

Source: https://habr.com/ru/post/1655256/


All Articles