返回集合的通用方法,给出不安全的类型转换警告

use*_*030 0 java generics types

当我定义一个返回Type类的方法时,我不能用任何扩展Base的类型覆盖该方法吗?请看以下示例:

MultiEntryModel.java(父类)

protected abstract <T extends Model> List<T> getDataList();
Run Code Online (Sandbox Code Playgroud)

ProgramData.java

public class ProgramData extends MultiEntryModel {
    ...
       @Override
        protected List<Program> getDataList() {
            return programs;
        }
}
Run Code Online (Sandbox Code Playgroud)

Program.java

public class Program extends Model {
   ...
}
Run Code Online (Sandbox Code Playgroud)

我在Programs.java中收到一个不安全的类型转换警告,即使我正在返回一个包含类型为Program的对象的List,它扩展了Model类,正如基类中的方法签名所示<T extends Model>.为什么?

And*_*ner 6

protected abstract <T extends Model> List<T> getDataList();
Run Code Online (Sandbox Code Playgroud)

这意味着列表将恢复其必须是安全的任何 T.例如:

List<SomeModel> someModelList = thing.getDataList();
Run Code Online (Sandbox Code Playgroud)

如果您要返回的列表是a List<Program>,则这将是不安全的 - 因为您可以SomeModel在该列表中添加一个,和/或您可以尝试SomeModel从列表中获取a .如果Program是子类型/超类型Program,那么这些操作中的一个是安全的; 否则,他们都不安全.

不要在方法上定义类型变量 - 将它放在类上:

abstract class TheClass<T extends Model> {
  protected abstract List<T> getDataList();
}

class ProgramClass extends TheClass<Program> {
  protected List<Program> getDataList() { return programs; }
}
Run Code Online (Sandbox Code Playgroud)

  • 调用者甚至没有绑定到"Model"的现有子类.使用`<T extends Model> List <T> getDataList()`的签名,我甚至可以写,`List <?扩展ExecutorService> list = getDataList();`,希望你返回一个实现`ExecutorService`的`Model`子类的实例列表...... (2认同)