9

在 Java 泛型中,Void 类型的对象和无界通配符类型的对象有什么区别?我的意思是我了解<?>的使用,也了解Void在反射方面的使用,但是当我看到Java源代码时我有点好奇

java.util.concurrent.AbstractExecutorService

及其方法

public Future<?> submit(Runnable task) {
    ...
    RunnableFuture<Void> ftask = new TaskFor(task, null);
    ...
    return ftask;

在方法内部它使用 RunnableFuture<Void> 而不是 RunnableFuture<?>

有人可以帮我理解这背后的原因吗?谢谢

4

3 回答 3

16

void是一个特殊的类,用来表示没有返回值。Void 虽然本身没有什么特别之处,但它不能(也永远不会)被实例化,所以它唯一可能的值是 always null。它用于两件事:

  1. 说泛型方法或类没有返回值。
  2. 使用 .来表示voidJava 反射中的返回类型Void.TYPE。例如,请参阅如何通过反射确定方法是否返回“void”

所以它与通配符非常不同,通配符不是实际的类,而是在编译时代表一种特定的、未知的类型。在运行时,它像所有其他泛型类型一样被擦除。


关于submit方法。以下是 JDK 6 的两个实现:

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Object> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}

和 JDK 7:

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}

如您所见,该类型Void仅在 JDK 7 中更改为,可能是因为它在概念上更有意义。但是由于方法的接口不能改变(出于兼容性原因,并且因为方法实现Future<?> submit(Runnable task)ExecutorService接口),所以返回类型Future<?>保持不变。这就是我的解释。

于 2012-10-18T19:26:17.383 回答
4

void 不是通配符,它​​表示根本没有要返回的值。

无效的javadoc ...

于 2012-10-18T19:22:41.237 回答
3

void是 void 的对象表示。void 从方法中不返回任何内容,而 Void 总是返回 null。这是因为 void 不是对象,因此不能与泛型一起使用。当您不需要任何返回值时,最好将 Void 与 Futures 一起使用。

于 2012-10-18T19:48:37.693 回答