问题
The compiler won't permit me to keep <X,Y> on the last line and I do not understand why.
How do I get such a generic construction to compile?
I tried changing the code to this:
X a = new A<X,Y>(); // "Type mismatch: cannot convert from A<X,Y> to X"
Y b = new B<X,Y>(); // "Type mismatch: cannot convert from B<X,Y> to Y"
W<X,Y> s = new M<X,Y>(a,b); // no error
I am a bit lost - please help!
回答1:
The constructor of M< X, Y > expects to receive an X and a Y, but you're trying to give it an IA< X, Y > and an IB< X, Y >. The necessary relationships are reversed; X is an IA< X, Y >, but not vice-versa, and similarly for Y.
The following compiles, but appears to be not restrictive enough for what you are after:
class A<X extends IA<X,Y>, Y extends IB<X,Y>> implements IA<X,Y>{}
class B<X extends IA<X,Y>, Y extends IB<X,Y>> implements IB<X,Y>{}
interface IA<X extends IA<X,Y>, Y extends IB<X,Y>> {}
interface IB<X extends IA<X,Y>, Y extends IB<X,Y>> {}
class M<X extends IA<X,Y>, Y extends IB<X,Y>> extends W<X,Y>{
public M(IA<X,Y> x, IB<X,Y> y){} // this is the only change
}
class W<X extends IA<X,Y>, Y extends IB<X,Y>> {}
//To my check class code:
public <X extends IA<X,Y>, Y extends IB<X,Y>> void check() {
IA<X,Y> a = new A<X,Y>();
IB<X,Y> b = new B<X,Y>();
W<X,Y> s = new M<X,Y>(a,b);
}
回答2:
The question involves a lot of generic constraints that don't make sense. M<X,Y>'s constructor takes arguments of types X and Y, which are type parameters of the generic method check (that means the caller can decide X and Y to be anything and this needs to still work). So why do you expect a and b (or anything else for that matter) to be the right type?
If you want to ask how to change generics constraints so that it works, here is a much simpler thing (it just changes generics (but keeps W and M as they are) and nothing else from the original) that compiles, and is probably closer to what you wanted anyway:
public interface IA<X, Y> {}
public interface IB<X, Y> {}
public class A implements IA<A,B>{}
public class B implements IB<A,B>{}
public class M<X extends IA<X,Y>, Y extends IB<X,Y>> extends W<X,Y>{
public M(X x, Y y){}
}
public class W<X extends IA<X,Y>, Y extends IB<X,Y>> {}
//To my check class code:
public void check() {
A a = new A();
B b = new B();
W<A,B> s = new M<A,B>(a,b);
}
回答3:
Although I saw you don't want to do it:
@SuppressWarnings("unchecked")
W<X,Y> s = new M<X,Y>((X) a,(Y) b);
does work.
As Judge Mental mentioned, your problem is too abstract and it is difficult for us to offer meaningful help. For example, in the check method, you are creating new A<X,Y>(). What does that mean? You don't define X and Y. There would never be such a method in real code.
来源:https://stackoverflow.com/questions/11465373/how-i-instantiate-include-code