コンパイラに差があるのはおいといて。。。
そもそも Z を型パラメータに含めるのが間違っているのかもしれない。というとこで Foo2。だいたい getZ が怪しい気もする。まえの例では X と Y に関係があったけど、そうじゃなくて。さらに W がいて、X と W は Z 経由でつながっていて、戻り値が X で引数が W の場合で、X と W が Z でつながらない場合はコンパイルエラーにしたい。まぁ Foo3 みたいなの。てのが Eclipse 上でもできてなかったってことか。来週の仕事でちゃんと考えよう。
package gen;
public class Foo2 {
public static interface ID<T1, T2> {
public T1 getValue(T2 arg);
}
public static interface IA<B> {
}
public static class A1 implements IA<B1> {
}
public static class B1 {
}
public static class E1 implements ID<A1, B1> {
public A1 getValue(B1 arg) {
return new A1();
};
}
public static class A2 implements IA<B2> {
}
public static class B2 {
}
public static class E2 implements ID<A2, B2> {
public A2 getValue(B2 arg) {
return new A2();
};
}
@SuppressWarnings("unchecked")
private <Z> Z getZ(Object y) {
if (y instanceof B1) {
return (Z) new E1();
}
if (y instanceof B2) {
return (Z) new E2();
}
return null;
}
public <X extends IA<Y>, Y> X bar(Y y) {
ID<X, Y> z = this.<ID<X, Y>> getZ(y);
return z.getValue(y);
}
public static void main(String[] args) {
Foo2 foo = new Foo2();
A1 a1 = foo.bar(new B1());
System.out.println(a1);
A2 a2 = foo.bar(new B2());
System.out.println(a2);
// コンパイルエラーとなる。
// a1 = foo.bar(new B2());
}
}
package gen;
public class Foo3 {
public static interface ID<T1, T2, T3> {
public T1 getValue(T2 arg);
public T1 getValue3(T3 arg);
}
public static interface IA<B> {
}
public static class A1 implements IA<B1> {
}
public static class B1 {
}
public static class C1 {
}
public static class E1 implements ID<A1, B1, C1> {
public A1 getValue(B1 arg) {
return new A1();
};
public A1 getValue3(C1 arg) {
return new A1();
}
}
public static class A2 implements IA<B2> {
}
public static class B2 {
}
public static class C2 {
}
public static class E2 implements ID<A2, B2, C2> {
public A2 getValue(B2 arg) {
return new A2();
};
public A2 getValue3(C2 arg) {
return new A2();
}
}
@SuppressWarnings("unchecked")
private <Z> Z getZ(Object y) {
if (y instanceof B1 || y instanceof C1) {
return (Z) new E1();
}
if (y instanceof B2 || y instanceof C2) {
return (Z) new E2();
}
return null;
}
public <X extends IA<Y>, Y> X bar(Y y) {
ID<X, Y, Object> z = this.<ID<X, Y, Object>> getZ(y);
return z.getValue(y);
}
public <A, C, E extends ID<A, ?, C>> A baz(C c) {
E z = this.<E> getZ(c);
return z.getValue3(c);
}
public static void main(String[] args) {
Foo3 foo = new Foo3();
A1 a1 = foo.bar(new B1());
System.out.println(a1);
A2 a2 = foo.bar(new B2());
System.out.println(a2);
a1 = foo.baz(new C1());
System.out.println(a1);
a2 = foo.baz(new C2());
System.out.println(a1);
// これはちゃんとコンパイルエラーになる。
// a1 = foo.bar(new B2());
// これもコンパイルエラーにしたい。
a1 = foo.baz(new C2());
}
}
それはともかく体調悪いな。仕事で無理しすぎだな。