Возврат универсального дочернего типа в общий родительский тип в java

У меня было много вопросов, связанных с 9X_jre этим, и я не мог решить свою проблему.

Вот 9X_java-generics мой вопрос.

У меня есть родительский абстрактный 9X_oraclejdk класс.

public abstract class Parent{ }

У меня есть еще два дочерних класса, которые 9X_generics расширены из вышеприведенного родительского 9X_jdk класса.

public class ChildOne extends Parent{}
public class ChildTwo extends Parent{}

В другом классе я использую эти три 9X_java-generics класса, как показано ниже.

public class A{ 
   public List> getExcelRecords() {
      ChildOne childone = new ChildOne();
      List> list = new ArrayList<>();

      // some logic here

      return list; // **compilation here**
   }
}

Код выдает следующую 9X_generic-programming ошибку компиляции:

required: List>
provided: List>

Мне нужно вернуть дочерний 9X_inheritence универсальный тип родительскому универсальному 9X_java типу. Как я могу этого добиться?

Примечание возвращаемое 9X_jre значение этого метода используется в устаревшем 9X_inheritence коде, который нельзя изменить соответствующим 9X_j2se образом. Должно остаться List>.

2
0
2
Общее количество ответов: 2

Ответ #1

Ответ на вопрос: Возврат универсального дочернего типа в общий родительский тип в java

Используйте подстановочные знаки в типе 9X_j2se возвращаемого значения. Этот подстановочный 9X_generics знак будет принимать любой класс, который 9X_java расширяет родительский класс


public List> getExcelRecords() {
   //...
}

Не стесняйтесь 9X_jdk проверить Java Generics FAQ для более подробной информации

14
0

Ответ #2

Ответ на вопрос: Возврат универсального дочернего типа в общий родительский тип в java

Вместо использования подстановочного знака 9X_jdk с верхней границей ? extends есть способ оставить 9X_generics нетронутым возвращаемый тип метода List>.

И, как 9X_jre вы указали в вопросе, это обязательное требование.

Возвращаемое 9X_inheritance значение этого метода будет использоваться 9X_generic в устаревшем методе, который нельзя изменить соответственно.

Как 9X_openjdk это будет работать?

Предположим, у нас есть 9X_generics следующий манекен ExcelRecord

public class ExcelRecord {
    private T item;

    public ExcelRecord(T item) {
        this.item = item;
    }
}

Если список был объявлен 9X_generic-programming так:

List> records = new ArrayList<>();

Мы сможем добавлять только объекты типа 9X_oraclejdk ExcelRecord (или подтипы ExcelRecord, имеющие общий тип Parent, скажем, SubExcelRecord).

Но 9X_jre обратите внимание, что ExcelRecord само может иметь свойство item типа parent 9X_inheritence Parent или его подтипа, т.е. мы можем хранить 9X_jre в нем 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_inheritance приведенные ниже строки будут успешно скомпилированы 9X_jre благодаря Java 8 target types.

// assignment context
ExcelRecord record1 = new ExcelRecord<>(new ChildOne());

// method invocation context
records.add(new ExcelRecord<>(new ChildTwo()));

В обоих случаях new ExcelRecord<>() является 9X_jre так называемым поливыражением, т. е. его тип будет зависеть 9X_java-generics от контекста, в котором оно появляется. В 9X_java первом случае компилятор выведет тип из 9X_inherit контекста присваивания, во втором — из контекста вызова.

Обратите внимание, если вы сделаете что-то 9X_inheritance подобное в своем коде, он не скомпилируется. Ваши 9X_javax записи должны быть типа Parent.

ExcelRecord record1 = new ExcelRecord<>(new ChildOne());
records.add(record1); // would raise a complition error

4
0