0

这是我的代码:

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();
    }
}

我的代码中到处都是错误。我真的很困惑。我在这里想念什么?

4

1 回答 1

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()has 签名的类时,您需要将Class对象作为类型标记传递给它。Java 编译器无法根据您分配返回值的变量的类型来推断类型。此外,由于类型擦除,您无论如何都希望它们在那里,否则您无法Creator根据给定的类型专门化它们。
    • 如果你有Base<J, I>两个类型参数,扩展类应该使用这两个类型参数。
    • 您的扩展类签名很奇怪。你不能拥有class Extension1 extends Base<Integer, InterfaceA<String>>,因为你不能拥有Creator<Integer, InterfaceA<String>>。使用显式类型标记createCreator()会迫使您在任何需要的地方传播此约束,并使错误不那么神秘。您不能真正独立于和类型参数Base之间的约束。JI
于 2012-06-24T11:34:15.053 回答