需要与对象创建者的技巧

时间:2012-06-24 06:22:57

标签: java java-ee

这是我的代码:

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 {
    // …
}

我希望Extension1Creator<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();
    }
}

我的代码中出现了错误。我真的很困惑。我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

你错过了很多东西,编译版本看起来像这样:

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