Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将泛型类型强制转换为对象?_Java - Fatal编程技术网

Java 如何将泛型类型强制转换为对象?

Java 如何将泛型类型强制转换为对象?,java,Java,下面的代码无法编译,因为它无法将任务添加到列表如何修复 import java.util.ArrayList; import java.util.List; public class Tasks { private final List<Task<Object>> queue = new ArrayList<>(); public static abstract class Task<T> {} public <T>

下面的代码无法编译,因为它无法将
任务添加到
列表
如何修复

import java.util.ArrayList;
import java.util.List;

public class Tasks {

  private final List<Task<Object>> queue = new ArrayList<>();

  public static abstract class Task<T> {}

  public <T> List<T> process(List<Task<T>> tasks) {
    for (Task<T> task : tasks) queue.add(task); // <== problem here
  }

}
import java.util.ArrayList;
导入java.util.List;
公开课任务{
私有最终列表队列=新的ArrayList();
公共静态抽象类任务{}
公共列表过程(列表任务){

对于(Task-Task:tasks)queue.add(Task);//想象任务与
List
完全相同:它有一个
add(T项)
方法

如果允许将
任务
添加到
任务
列表中,那么其他代码可以从列表中获取一个项目,该项目的类型为
任务
,这样您就可以调用
添加(对象o)
方法,让您添加任何您想要的内容,因为任何内容都是对象

因此,如果您添加了一个
任务
,您的任务中现在就没有字符串了

这就是为什么这是不允许的

现在,假设您的任务绝对没有机会“添加”东西;没有一个方法将T作为参数,T仅出现在“get”位置,在学术语言中,作为协变选项:例如,它仅显示在
任务
类中的方法返回类型中

不幸的是,Java没有那种使用站点差异声明模型来简化这一过程

您有两种通用解决方案:

  • “uglycasting”:使用Cast构造的第三种形式强制转换内容,其中您强制转换为具有泛型的类型,或者可能是原始类型:
  • 然后使用
    @SuppressWarnings
    。请注意,这意味着您正在“选择退出”编译器检查您的工作,如果任务有类似于
    add(T)的方法
    或稍后获得一个,您将无法获得任何保护,最终结果很可能是您最终会在零强制转换的位置看到
    ClassCastException
    错误

  • 重新定义
    队列

  • 或者,重新定义队列以接受协方差。从这个意义上说,
    Task
    是毫无用处的;您将创建的任务类型很少甚至没有可分配给此类型。请尝试
    Task
    。就像使用
    列表一样,如果您存储的是混合任务类型,则需要使用
    ,因为您的列表不知道任务类型
    任务
    将被传递到其中

    private final List>queue=new ArrayList();
    //类方法
    公共列表进程(列表任务:任务)队列。添加(任务);
    返回queue.stream().map(Task::getValue.collect(Collectors.toList());
    }
    //实施
    私有静态类StringTask扩展任务{
    受保护的StringTask(字符串值){
    超级(价值);
    }
    }
    私有静态类IntTask扩展任务{
    受保护的IntTask(整数值){
    超级(价值);
    }
    }
    公共静态void main(字符串[]args){
    任务=新任务();
    
    List@ajc2000
    T
    过程
    方法之外没有任何意义。您可以使用
    List
    私有最终列表。按照上面的建议
    列表
    怎么样?扩展对象
    是多余的,因为一切都扩展了对象,我会按照别人的建议执行
    Task /* raw */ temp = task;
    queue.add(temp); // this will work, but generates a warning.