java.lang.Void与void与Null的区别

20

Voidvoid之间的区别是什么?我能否用null代替它们?

我问这个问题是因为我看了一些示例Android代码,他们使用了Void,但Eclipse显示错误(它说“Void无法解析为变量”)。

我的出错代码是:

public class MyAsyncTask extends AsyncTask<Void, Void, Boolean>{
    ...
}

我使用它的方式如下:

MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute((Void),null);//this is the line that breaks  "Void cannot be resolved to a variable"

如果我们能看到出错的代码,那会很有帮助。 - Louis Wasserman
我要添加一个小片段。只是清理一下。 - Josh
顺便说一下,你也可以尝试使用myAsyncTask.execute(new Void[1]); =D - Protect Life Save Forests
没有 Null 类型。 - shmosel
@shmosel 公平,但从技术上讲是不正确的,但我认为这就是问题所在,所以我批准了编辑,但将标题更改回原始的“Null”。 - Josh
参见 https://dev59.com/YGgv5IYBdhLWcg3wHNLG - blueberryfields
5个回答

61
Void最常见的用途是反射,但这不是它唯一的使用场合。 void是一个关键字,表示函数没有返回值。 java.lang.Void是一个引用类型,因此以下是有效的:
 Void nil = null;

迄今为止这并不有趣...

作为结果类型(一种返回值类型为Void的函数),这意味着该函数*始终*返回null(它不能返回除null之外的任何内容,因为Void没有实例)。

 Void function(int a, int b) {
    //do something
    return null;
 }

为什么我需要一个总是返回 null 的函数?

在泛型出现之前,我没有使用 Void 的用例。

有了泛型,就有了一些有趣的情况。例如,Future<T> 是一个保存由其他线程执行的异步操作结果的容器。 Future.get 将返回操作值(类型为 T),并阻塞直到计算完成。

但是......如果没有要返回的内容怎么办?简单:使用 Future<Void>。例如,在 Google App Engine 中,异步数据存储服务delete 操作将返回一个 Future<Void>。当在该 future 上调用 get() 时,删除完成后将返回 nullCallable 可以写类似的示例。

另一个用例是没有值的 Map,即 Map<T,Void>。这样的地图的行为类似于 Set<T>,因此当没有等效的 Set 实现时可能会有用(例如,没有 WeakHashSet,则可以使用WeakHashMap<T,Void>)。


4

3
你的代码中有一个额外的逗号。
myAsyncTask.execute((Void),null);
                        //^extra comma right here

此外,没有必要将null强制转换为Void,因为(1)Void没有实例,因此不存在Void对象,(2)将null转换为任何类型都是相当无用的,因为null是任何Object数据类型的有效值。
代码应该只是这样的:
myAsyncTask.execute(null);

1
这是程序相关内容的翻译:这是多余的逗号。谢谢!我没有意识到它是一个类型转换(我以为它是两个参数),但出于某种原因,它必须进行类型转换,否则会出现错误,指出“execute(void[])对于类型MyAsyncTask存在歧义”。 - Josh
2
在这种情况下,最稳妥的方法实际上是 myAsyncTask.execute(); - battery

2

java.lang.Voidvoid类型的封装表示。由于您无法拥有void类型的实例,因此它主要用于完整性和非常罕见的需要反射的情况。


java.lang.Void 不是 void装箱表示。称其为装箱表示意味着你正在包装一个基本类型。void 不是基本类型,也不是类型,因此没有任何包装发生。 - Jeffrey
一些资源,例如http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Java_Primitive_Types.html,将`void`列为原始类型。它肯定不是一个类。它的整个目的是代表具有相同目的的基本类型,这正是“装箱表示”实际上所做的。 - Wug
Java 语言规范 指出 void 不是一种类型。 - Jeffrey
很有趣。因为当我查看Void类的代码时,我发现public static final Class<Void> TYPE = (Class<Void>) Class.getPrimitiveClass("void");,这表明void被视为原始类型。 - Reza

1

void:Java关键字,表示方法不会返回任何内容。用于方法。

Void:void的包装器。它扩展了Object类。

由于泛型不支持原始数据类型,因此需要使用它。(虽然void被认为是原始数据类型,但这只是为了解释)

应该用于反射。

Constructor<Void> constructor = Void.class.getConstructor()

null表示无值。与void用于方法相比,它用于对象的比较。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接