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