Java泛型中Void类型的对象与无界通配符类型的对象有什么区别?我的意思是我理解的用法,以及理解Void的用法,但是当我看到Java的源代码时,我对此有些兴趣

java.util.concurrent.AbstractExecutorService

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

在方法内部使用RunnableFuture 代替RunnableFuture
有人可以帮助我了解背后的原因吗?谢谢

最佳答案

Void是一个特殊的类,用于表示没有返回值。尽管Void本身没有什么特别的,但是它不能(也永远不会)被实例化,因此,唯一可能的值始终是null。它用于两件事:

  • 要说通用方法或类没有返回值。
  • 使用void表示Java反射中的Void.TYPE返回类型。例如,参见How to determine by reflection if a Method returns 'void'

  • 因此,它与通配符非常不同,通配符不是实际的类,但在编译时表示一种特定的未知类型。在运行时,它像其他所有通用类型一样是erased

    关于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;
    }
    

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

    07-24 09:49
    查看更多