Saw this post yesterday: How I instantiate? Include code
The user could not get the constructor type of a generic class, X to match the type of the object passed into the constructor, IA, even though <X extends IA>.
I didnt really like the only answer provided, as it made the whole point of generics useless if you have to change the M constructor type from X to IA<X>. Surely this is why the generic type for M is <X extends IA>??
Is there really no way to use generics (without any suppressed warnings) for this basic example?
public interface IA<X extends IA<X>>{}
public class A<X extends IA<X>> implements IA<X>{}
public class W<X extends IA<X>>{}
public class M<X extends IA<X>> extends W<X>{
X anx;
public M(X x){} //Type X here is not compatibile with IA in the test code
}
//Testing code in a different class
public <X extends IA<X>> void check() {
IA<X> a = new A<X>();
W<X> s = new M<X>(a); //Doesn't compile because IA<X> is not the same as 'X', even though <X extends IA>
W<X> s = new M(a); //Compiles, but with suppressed warnings
X a = new A<X>(); //Doesnt compiler (ignoring dupicate 'a' variable)
W<X> s = new M<X>(a); compiles
}
edited to include IA everywhere including ‘extends’
You have to do something like this:
Regarding the warnings, I think they are self-explanatory and they can be summarized as: When you have a generically parameterized type whenever you wan to use it, you have to instantiate the generic parameter to a concrete type. Generic parameters have been introduced in order to generalize code but also to enforce type safeness. Using IA means you throw away the type safety you could’ve gotten by saying : IA < ASpecificType > and the compiler draws your attention on this.
The following code is the closest I could get to your code and at the same time to make some sense: