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@ajc2000T
在过程
方法之外没有任何意义。您可以使用List私有最终列表。按照上面的建议列表
怎么样?扩展对象
是多余的,因为一切都扩展了对象,我会按照别人的建议执行?
Task /* raw */ temp = task;
queue.add(temp); // this will work, but generates a warning.