也使通用:Bar
class Bar<T> {
private Foo<T> var1;
private Foo<T> var2;
public Bar(Foo<T> var1, Foo<T> var2) {
this.var1 = var1;
this.var2 = var2;
}
public static void main(String[] args) {
Foo<String> var1 = new Foo<>();
Foo<Integer> var2 = new Foo<>();
Bar<String> b = new Bar<>(var1, var2); // this does not work
}
}
通过使用 的类级泛型参数,您可以为两个实例变量强制实施相同的类型。T
Bar
这也消除了使用原始类型(永远不应该使用)的警告,正如@daniu在注释中提到的。
现在,如果您碰巧不使用原始类型,但希望允许不同的类型,则可以使用通配符:
使用上限,它只允许类型化读取(并且将始终产生类型的实现):var1
var2
T
class Bar<T> {
private Foo<? extends T> var1;
private Foo<? extends T> var2;
public Bar(Foo<? extends T> var1, Foo<? extends T> var2) {
this.var1 = var1;
this.var2 = var2;
}
public static void main(String[] args) {
Foo<String> var1 = new Foo<>();
Foo<Integer> var2 = new Foo<>();
Bar<Object> b = new Bar<>(var1, var2); // this does now work
}
}
而使用下限,它只允许类型化写作(并且将始终使用类型的任何实现):var1
var2
T
class Bar<T> {
private Foo<? super T> var1;
private Foo<? super T> var2;
public Bar(Foo<? super T> var1, Foo<? super T> var2) {
this.var1 = var1;
this.var2 = var2;
}
public static void main(String[] args) {
Foo<Integer> var1 = new Foo<>();
Foo<Number> var2 = new Foo<>();
Bar<Integer> b = new Bar<>(var1, var2); // this does now work
}
}
有关该主题的更多信息,您可以阅读:什么是PECS(生产者扩展消费者超级)?