那为什么FutureTask<Integer> fu=new FutureTask<Integer>(ca);换成Future fu就会报错
时间: 2024-04-04 10:31:08 浏览: 53
在Java中,泛型是Java 5之后引入的一个特性,它可以让我们在编译时就能够检查类型安全,从而避免类型转换异常等问题。
在这个问题中,FutureTask是一个泛型类,它的构造函数需要传递一个Callable对象,所以声明FutureTask对象时,需要指定泛型类型,例如FutureTask<Integer> fu = new FutureTask<Integer>(ca)。
如果你将其改为Future fu = new FutureTask(ca),那么编译器就无法确定FutureTask的泛型类型是什么,因此会报错。
因此,如果你不确定FutureTask需要的泛型类型是什么,可以使用通配符类型 FutureTask<?> fu = new FutureTask<>(ca)。这样就可以不指定具体的泛型类型,但是也不能在后面的代码中使用泛型中的具体类型。
相关问题
那为什么FutureTask<Integer> fu=new FutureTask<Integer>(ca);换成Future<Interger> fu就会报错
在Java中,泛型是Java 5之后引入的一个特性,它可以让我们在编译时就能够检查类型安全,从而避免类型转换异常等问题。
在这个问题中,FutureTask是一个泛型类,它的泛型类型是指它的返回值类型,如果你将其改为Future<Integer> fu = new FutureTask<>(ca),编译器会认为你声明的是一个返回值类型为Integer的Future对象,但是实际上你创建的是一个FutureTask对象,两者的类型不匹配,因此会报错。
如果你想要使用Future接口来引用FutureTask对象,可以将其声明为 FutureTask<Integer> fu = new FutureTask<>(ca),这样就可以通过FutureTask实现Future接口的功能,同时保留了泛型类型的正确性。
import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; public class ThreeThread { public static void main(String[] args) { //工作线程 Worker worker = new Worker(); //使用 FutrueTask 包装 Callable 对象 FutureTask<Integer> ft = new FutureTask<>(worker); for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "循环变量i的值:" + i); if (i == 5) { new Thread(ft, "有返回值的线程").start(); new Thread(ft, "1").start(); } } } //创建 Callable 接口的实现类 public static class Worker implements Callable<Integer> { // Class 'Worker' must either be declared abstract or implement abstract method 'call()' in 'Callable' @Override public Integer call() throws Exception { int t = 0; for (; t < 10; t++) { System.out.println(Thread.currentThread().getName() + "循环变量t的值:" + t); } return t; } } }代码只输出一个子线程信息
这段代码中,使用了一个FutureTask对象ft来包装Callable接口实现类Worker的实例对象worker,并将ft传递给一个新线程,并启动该线程。当循环变量i的值等于5时,会启动两个新线程,都使用了同一个FutureTask对象ft,因此会输出两个子线程信息,但是它们都在执行同一个Callable对象的call()方法,因此输出的内容是相同的。在主线程中,没有调用ft.get()方法获取子线程的返回值,因此不会输出子线程的返回值。
阅读全文