first time posting and sorry the title is probably rubbish. I'm trying to use type inference but struggling to make it work properly when using a factory pattern, let me throw down some code to make this a bit clearer:
private class ParentObject { }
private class ChildObject extends ParentObject { }
private interface Template<T extends ParentObject> {
void doSomething(T object);
}
private class TemplateImpl implements Template<ChildObject> {
public void doSomething(ChildObject object) { }
}
So I've got some classes that inherit from Template that do something with an object that inherits from ParentObject (I've only posted one of each in this post). Now this problem I'm having is when I try to generate one of these Template classes I keep getting either an "incompatible types" error when I try to do this:
private class Factory {
public <T extends ParentObject> Template<T> generate() {
return new TemplateImpl(); // here is the error
}
}
private class Service {
public <T extends ParentObject> void magic() {
Factory f = new Factory();
Template<T> a = f.generate();
}
}
Or I get an "unchecked assignment" warning (the code works as intended like this but if I'm doing something wrong I'd rather fix it!) when I do this:
private class AlternativeFactory {
public Template generate() {
return new TemplateImpl();
}
}
private class Service {
public <T extends ParentObject> void magic() {
AlternativeFactory af = new AlternativeFactory();
Template<T> b = af.generate(); // warning here
}
}
Does anyone have any insight onto how I can make this work without any warnings? I've not used type-inference much so apologies if this is a simple one! What I'm not understanding is why I can't return TemplateImpl as a Template given it implements Template?
Thanks!
EDIT: In fact, the factory I want to implement looks something like this, and it seems this is where the issue around type-inference exists:
private class Factory {
public Template<T extends ParentObject> generate(int option) {
switch (option) {
case 1:
return new TemplateA(); // implements Template<A> where A extends ParentObject
case 2:
return new TemplateB(); // implements Template<B> where B extends ParentObject
default:
throw new IllegalArgumentException();
}
}
}
EDIT: Decided to go with the code I provided above (AlternativeFactory) and just use SuppressWarnings in the service method that calls the factory since it seems what I hoped to achieve is not possible. I know this uses raw types and is bad practise but I have lots of tests around these Template objects and AlternativeFactory including type checks so this will have to do for now.