我将要创建一个工厂,它创建某种类型 T 的对象,它扩展了某个类 A 和另一个接口(interface) I。但是,T 一定是未知的。以下是最低限度的声明:
public class A { }
public interface I { }
这是工厂方法:
public class F {
public static <T extends A & I> T newThing() { /*...*/ }
}
编译一切正常。
当我尝试使用以下方法时,效果很好:
A $a = F.newThing();
...虽然这不是:
I $i = F.newThing();
编译器提示:
Bound mismatch: The generic method newThing() of type F is not applicable for the arguments (). The inferred type I&A is not a valid substitute for the bounded parameter
我不明白为什么。明确指出“newThing 返回某种类型 T 的东西,它确实扩展了类 A 并实现了接口(interface) I”。当分配给 A 时一切正常(因为 T 扩展了 A)但分配给 I 却不行(因为什么?,显然返回的东西是既是 A 又是 一个 I)
另外:当返回一个对象时,假设类型为 class B extends A implements I
的 B,我需要将其转换为返回类型 T,尽管 B 匹配边界:
<T extends A & I> T newThing() {
return (T) new B();
}
但是,编译器不会抛出任何类似 UncheckedCast 之类的警告。
因此我的问题是:
- 这里出了什么问题?
- 有没有一种方法可以轻松实现所需的行为(即分配给静态类型 A 或 I 的变量),就像在工厂方法中通过强制转换解决返回类型问题一样?
- 为什么分配给 A 有效,而分配给 I 却不行?
--
编辑:这里是完全使用 Eclipse 3.7 的完整代码片段,为 JDK 6 设置的项目:
public class F {
public static class A { }
public static interface I { }
private static class B extends A implements I { }
public static <T extends A & I> T newThing() {
return (T) new B();
}
public static void main(String... _) {
A $a = F.newThing();
// I $i = F.newThing();
}
}
编辑:这是一个包含方法和调用的完整示例,在运行时运行:
public class F {
public static class A {
int methodA() {
return 7;
}
}
public static interface I {
int methodI();
}
private static class B extends A implements I {
public int methodI() {
return 12;
}
}
public static <T extends A & I> T newThing() {
return (T) new B();
}
public static void main(String... _) {
A $a = F.newThing();
// I $i = F.newThing();
System.out.println($a.methodA());
}
}
最佳答案
关于第二个问题:
考虑这种情况:
class B extends A implements I {}
class C extends A implements I {}
现在,以下使用类型推断:
<T extends A & I> T newThing() {
return (T) new B();
}
所以你可以这样称呼:
C c = F.newThing(); //T would be C here
T
可以是 任何 扩展 A
和 I
你不能只返回一个B
的实例。在上面的例子中,转换可以写成(C)new B()
。这显然会导致异常,因此编译器会发出警告:Unchecked cast from B to T
- unless you're supressing those warnings.
关于Java 泛型 : Multiple Inheritance in Bounded Type Parameters <T extends A & I>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9824831/