这是我的代码:
public interface InterfaceA<J>{
// …
}
public interface InterfaceB extends InterfaceA<String> {
// …
}
public interface InterfaceC extends InterfaceA<Long>{
// …
}
public class Creator<J, I extends InterfaceA<J>> {}
public abstract class Base<J, J1> implements InterfaceA<J> {
protected Creator<J, J1> creator;
protected Base() {
creator=ObjectCreator.createCreator();
}
}
public class Extension1 extends Base<Integer> implements InterfaceB {
// …
}
public class Extension2 extends Base<Double> implements InterfaceC {
// …
}
我希望Extension1
拥有Creator<Integer, InterfaceB>
,Extension2
拥有Creator<Double, interfaceC>
。看到模式了吗? Creator<T1, T2>
其中T1
是直接父级的类型,T2
是所述类实现的接口。有什么办法可以做到这一点吗?谁能说出ObjectCreator.createCreator()
的代码?
现在我的代码如下所示:
public class ObjectCreator {
public static <J, I extends InterfaceA<J>> Creator<J, I> createCreator() {
return new Creator();
}
}
我的代码中到处都是错误。我真的很困惑。我在这里错过了什么?
你错过了一大堆东西,编译版本看起来像这样:
package scratch;
interface InterfaceA<J> {
// …
}
interface InterfaceB extends InterfaceA<String> {
// …
}
interface InterfaceC extends InterfaceA<Long> {
// …
}
class Creator<J, I extends InterfaceA<J>> {
}
abstract class Base<J, I extends InterfaceA<J>> {
protected Creator<J, I> creator;
protected Base(Class<J> jClass, Class<I> iClass) {
creator = ObjectCreator.createCreator(jClass, iClass);
}
}
class Extension1 extends Base<String, InterfaceB> implements InterfaceB {
protected Extension1() {
super(String.class, InterfaceB.class);
}
}
class Extension2 extends Base<Long, InterfaceC> implements InterfaceC {
protected Extension2() {
super(Long.class, InterfaceC.class);
}
}
class ObjectCreator {
public static <J, I extends InterfaceA<J>> Creator<J, I>
createCreator(Class<J> jClass, Class<I> iClass) {
return new Creator();
}
}
重要性不分先后:
- 当你有一个像
createCreator()
一样带有签名的类时,你需要Class
对象作为类型标记传递给它。Java 编译器无法根据要为其分配返回值的变量的类型推断类型。此外,由于类型擦除,您无论如何都希望它们在那里,否则您无法根据给定的类型专门化Creator
。- 如果
Base<J, I>
有两个类型参数,则扩展类应同时使用这两个类型参数。 - 您的扩展类签名很奇怪。你不能有
class Extension1 extends Base<Integer, InterfaceA<String>>
,因为你不能有Creator<Integer, InterfaceA<String>>
。在createCreator()
中使用显式类型标记会迫使您将此约束传播到需要的任何位置,并使错误不那么神秘。您不能真正使Base
独立于J
和I
类型参数之间的约束。
- 如果