Ответ 1
Make 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 (продюсер продлевает потребительский супер)?