Возврат универсального дочернего типа в общий родительский тип в java
У меня было много вопросов, связанных с 9X_generic этим, и я не мог решить свою проблему.
Вот 9X_jre мой вопрос.
У меня есть родительский абстрактный 9X_java-generics класс.
public abstract class Parent{ }
У меня есть еще два дочерних класса, которые 9X_jre расширены из вышеприведенного родительского 9X_inheritence класса.
public class ChildOne extends Parent{}
public class ChildTwo extends Parent{}
В другом классе я использую эти три 9X_javax класса, как показано ниже.
public class A{
public List> getExcelRecords() {
ChildOne childone = new ChildOne();
List> list = new ArrayList<>();
// some logic here
return list; // **compilation here**
}
}
Код выдает следующую 9X_inherit ошибку компиляции:
required: List>
provided: List>
Мне нужно вернуть дочерний 9X_java-generics универсальный тип родительскому универсальному 9X_generics типу. Как я могу этого добиться?
Примечание возвращаемое 9X_swift-generics значение этого метода используется в устаревшем 9X_inherit коде, который нельзя изменить соответствующим 9X_openjdk образом. Должно остаться List
.
Ответ #1
Ответ на вопрос: Возврат универсального дочернего типа в общий родительский тип в java
Используйте подстановочные знаки в типе 9X_jre возвращаемого значения. Этот подстановочный 9X_jre знак будет принимать любой класс, который 9X_swift-generics расширяет родительский класс
public List> getExcelRecords() {
//...
}
Не стесняйтесь 9X_generic-programming проверить Java Generics FAQ для более подробной информации
Ответ #2
Ответ на вопрос: Возврат универсального дочернего типа в общий родительский тип в java
Вместо использования подстановочного знака 9X_javax с верхней границей ? extends
есть способ оставить 9X_oraclejdk нетронутым возвращаемый тип метода List
.
И, как 9X_java-generics вы указали в вопросе, это обязательное требование.
Возвращаемое 9X_jre значение этого метода будет использоваться 9X_openjdk в устаревшем методе, который нельзя изменить соответственно.
Как 9X_oraclejdk это будет работать?
Предположим, у нас есть 9X_generics следующий манекен ExcelRecord
public class ExcelRecord {
private T item;
public ExcelRecord(T item) {
this.item = item;
}
}
Если список был объявлен 9X_j2se так:
List> records = new ArrayList<>();
Мы сможем добавлять только объекты типа 9X_generics ExcelRecord
(или подтипы ExcelRecord
, имеющие общий тип Parent
, скажем, SubExcelRecord
).
Но 9X_generic-programming обратите внимание, что ExcelRecord
само может иметь свойство item
типа parent 9X_oraclejdk Parent
или его подтипа, т.е. мы можем хранить 9X_generic-programming в нем ChildOne
или ChildTwo
. И код будет компилироваться 9X_oraclejdk и работать отлично.
Вот полный пример:
public List> getExcelRecords(){
List> records = new ArrayList<>();
ExcelRecord record1 = new ExcelRecord<>(new ChildOne()); // compiles fine
records.add(record1);
records.add(new ExcelRecord<>(new ChildTwo())); // fine as well
return records;
}
Leaving and breathing Online Demo
Обе 9X_generics приведенные ниже строки будут успешно скомпилированы 9X_oraclejdk благодаря Java 8 target types.
// assignment context
ExcelRecord record1 = new ExcelRecord<>(new ChildOne());
// method invocation context
records.add(new ExcelRecord<>(new ChildTwo()));
В обоих случаях new ExcelRecord<>()
является 9X_inheritance так называемым поливыражением, т. е. его тип будет зависеть 9X_java-generics от контекста, в котором оно появляется. В 9X_inherit первом случае компилятор выведет тип из 9X_oraclejdk контекста присваивания, во втором — из контекста вызова.
Обратите внимание, если вы сделаете что-то 9X_j2se подобное в своем коде, он не скомпилируется. Ваши 9X_generic записи должны быть типа Parent
.
ExcelRecord record1 = new ExcelRecord<>(new ChildOne());
records.add(record1); // would raise a complition error
-
2
-
2
-
14
-
2
-
4
-
1
-
3
-
1
-
10
-
5
-
7
-
7
-
4
-
4
-
3
-
4
-
4
-
2
-
3
-
3
-
3
-
2
-
3
-
5
-
1
-
10
-
10
-
12
-
5
-
10
-
10
-
7
-
15
-
7
-
6
-
5
-
4
-
3
-
2
-
8
-
6
-
9
-
6
-
6
-
14
-
6
-
14
-
4
-
9
-
7