Java泛型中的void/Void类型

100

我正在实现一个apache HttpClient软件包的ResponseHandler,如下所示:

new ResponseHandler<int>() {
    public int handleResponse(...) {
        // ... code ...
        return 0;
    }
}

但是我希望 handleResponse 函数不返回任何东西,即 void。这种情况是否可能?以下代码无法编译,因为 void 不是有效的 Java 类型:

new ResponseHandler<void>() {
        public void handleResponse(...) {
            // ... code ...
        }
}

我想我可以用 Void 替换 void,以返回一个 Void 对象,但那不是我真正想要的。 问题:是否有可能以这种方式组织回调情况,以便我可以从 handleResponse 返回 void

6个回答

111

Void类型是为了解决这种情况而创建的:创建一个具有通用返回类型的方法,其中子类型可以是“void”。Void被设计成无法创建该类型的任何对象。因此,类型为Void的方法将始终返回null(或异常完成),这是你能得到的最接近于“nothing”的东西。你确实需要在方法中放置return null,但这只是一个小不便。

简而言之:请使用Void


3
Arrgh - 泛型的痛苦问题是,如果您定义了“Void”作为返回类型,则必须放入“return(null);”。声明void返回类型的主要原因是,这样您就不必拥有返回语句,并且可以使用现有的“void”方法 :) Java泛型的问题之一是运行时类型检查与需要编译时代码生成和“bookeeping”辅助的混淆。人们需要提供“宏”和“模板”,以在语言方面编写代码时提供便利。 - peterk
6
为了澄清,Void 类型自 JDK 1.1 版本就已经存在。最初它是为了反射而创建的,但在泛型中也扮演着类似的角色。 - John McCarthy
@ILMTitan,您能否提供有关在定义返回Void的方法中使用“return null”语句的文档参考? - Andriy Simonov
具有返回类型为void的方法不必返回值。具有返回类型为Object或任何子类(例如Void)的方法必须返回一个值(或者不能正常完成)。唯一可以分配给Void并因此从Void方法返回的值是null - ILMTitan

75

泛型只处理对象类,不支持 void 和基本类型,你不能将它们用作参数化类型。你必须使用 Void 代替。

你能说一下为什么不想使用 Void 吗?


11
我更倾向于在没有返回任何东西的函数中不包含 return 语句,主要是为了代码的整洁性。 - Travis Webb
10
你可以创建一个抽象包装器,调用你的void方法并返回null来隐藏这个丑陋的细节。 - Peter Lawrey
55
谢谢你提醒我,“计算机科学中的任何问题都可以通过增加一层间接性来解决”。 - Travis Webb
@TravisWebb 根据您的具体需求,最好不要使用泛型,如果可以的话,返回 Object 类型即可。 - Chaitanya

16

当你需要返回java.lang.Void时,只需返回null


1

泛型中不能使用原始类型,因此int实际上是一个Integer。对象Void与泛型关键字void类似。


7
"void"不是一个基本数据类型,而只是Java中的关键字。它没有“类型”。 - Travis Webb
1
void(小写)- 关键字,不返回任何值;Void(大写)- 一个(无法实例化的),返回该类的实例(只能是 null,因为无法实例化)。 - user85421
@Carlos Heuberger,类似的选项是否更适合您? - mark-cs

0
这个 Java 中的 java.lang.Void 实现有点自解释性。我还写了一篇文章将其与泛型联系起来。在开始理解之前,我花了一些时间思考:http://www.siteconsortium.com/h/D00006.php。请注意 TYPE = Class.getPrimitiveClass("void");。
包 java.lang;
public final class Void {

    public static final Class<Void> TYPE = Class.getPrimitiveClass("void");

    private Void() {}
}

-1

很遗憾这是不可能的。你可以设置代码返回Void,但是你永远无法实例化一个Void,因此你实际上无法编写符合此规范的函数。

可以将其视为:通用函数表示“此函数返回类型为X的某些内容”,您可以指定X,但不能更改句子为“此函数不返回任何内容”。(我不确定我是否同意这些语义,但它们就是这样。)

在这种情况下,我总是将函数返回类型设置为Object,并且实际上始终返回null


2
因为使用返回类型为Object,编译器无法保证只返回null。扩展Thomas的答案,请尝试以下内容:static Void v() { return null; } static Void n() { return "NotAllowed"; } static Object o() { return "Allowed"; } - Nathan Niesen
1
是的,我知道,这在目前看来已经是古代历史了,但最近我来到这里,想指出这个答案实际上是不正确的。 你可以返回Void类型。虽然不能有此类型的实例化对象,但由于Java中所有对象类型都是可空的,因此可以返回null。 实质上,您使用Object类型所做的就是您应该使用Void类型所做的。Void类型正确地表示只会返回null。 - Daniel Skarbek

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