Java - 类公共API的边界

时间:2017-02-07 07:22:07

标签: java contravariance

我有一个ModelDecorator助手。我希望它具有以下公共API

class ModelDecorator<T>{
    public static <T> ModelDecorator<T> create(Class<T> clazz);
    public <SUPER> T from(SUPER fromInstance);
}

因此,给定类A,B扩展A,它可以像这样使用:

A a = new A();
B b = ModelDecorator.create(B.class).from(a);

但我希望对T和SUPER有界限,所以我确保只使用API​​实例化子块。此刻,我可以做到:

C c = new C();
B b = ModelDecorator.create(B.class).from(c);

其中B不从C继承。

有什么想法吗?感谢

1 个答案:

答案 0 :(得分:3)

我看到限制类型参数T以扩展类型参数S的唯一方法是将这些定义放入类定义中:

public class ModelDecorator<S, T extends S> {
    public static <S, T extends S> ModelDecorator<S, T> create(Class<T> clazz) { ... }
    public T from(S instance) { ... }
}

使用这些课程

class A {}
class B extends A {}
class C {}

您现在可以编写以下代码:

A a = new A();
B b1 = ModelDecorator.<A, B> create(B.class).from(a); // compiles fine

C c = new C();
B b2 = ModelDecorator.<C, B> create(B.class).from(c); // bound mismatch here

第二个B创建现在有编译错误。

不幸的是,您现在必须明确提供类型参数,因为编译器无法从简单的方法调用A推断出类型Ccreate(B.class)