需要对象创建者的技巧



这是我的代码:

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独立于JI类型参数之间的约束。

最新更新