Java泛型void / Void类型


78

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

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

但我希望handleResponse函数不返回任何值,即void。这可能吗?由于void不是有效的Java类型,因此以下内容无法编译:

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

我想可以替换voidVoid以返回Void对象,但这并不是我真正想要的。:是否有可能安排在这样一种方式,我可以返回此回调局面voidhandleResponse

Answers:


64

泛型仅处理对象类。泛型不支持void和基本类型,您不能将它们用作参数化类型。您必须改用Void。

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


8
我只是不想return在不返回任何内容的函数中包含语句,以确保整洁。
Travis Webb

8
您可以创建一个抽象包装器,该包装器将调用您的void方法并返回null以隐藏此丑陋状态。
彼得·劳瑞

47
+1提醒我“计算机科学中的任何问题都可以通过添加间接层来解决”
Travis Webb

@TravisWebb着眼于您的特定需求,就是根本不要使用泛型,Object如果可以的话就返回类型
Chaitanya

87

Void类型是针对这种确切情况而创建的:创建一个具有通用返回类型的方法,其中子类型可以为“ void”。Void设计这种方式时,可能无法创建该类型的对象。因此,类型方法Void将始终返回null(或异常完成),这与您将要获得的结果几乎一样。您必须return null输入该方法,但这仅是一个小麻烦。

简而言之:请使用Void


Arrgh-泛型的难题在于,如果让我们说您定义了返回类型“ Void”,则必须将其放入“ return(null);”;声明void返回类型的主要原因是这样,您不必具有return语句,并且可以使用现有的“ void”方法:) Java Generics的部分问题是运行时类型检查的合并需要编译时代码生成和“ bookeeper”帮助。人们需要“宏”和“模板”,以便在语言方面编写代码时很方便。
彼得

6
+1为了明确起见,Void自JDK1.1起就存在。它最初是为与Reflection一起使用而创建的,但在泛型中具有类似的作用。
约翰·麦卡锡

@ILMTitan您能否在定义为返回Void的方法中提供有关“ return null”语句的文档的任何引用?
安德里·西蒙诺夫

@ andriy-simonov返回类型为的方法void不必返回值。返回类型为Object或任何子类的方法Void必须返回一个值(或不能正常完成)。可以分配给唯一的值Void,并且从返回为此Void方法,是null
ILMTitan

8

当您需要返回时java.lang.Void,只需返回即可null


1

,这是不可能的。您可以Void按照您所说的那样设置代码以返回,但是您永远不能实例化a,Void因此您实际上不能编写符合此规范的函数。

可以将其视为:泛型函数说“此函数返回X类型的东西”,您可以指定X,但不能将句子更改为“此函数不返回任何东西”。(我不确定我是否同意这些语义,但事实就是这样。)

在这种情况下,我一直要做的只是使函数返回类型Object,而实际上总是return null


1
因为使用Object的返回类型,编译器无法保证仅返回null。扩大Thomas的答案,请尝试以下方法: static Void v() { return null; } static Void n() { return "NotAllowed"; } static Object o() { return "Allowed"; }
Nathan Niesen

1

您不能在泛型中包含基元,因此int实际上是Integer。该对象Void类似于void泛型关键字。


4
void不是原始的,它只是一个Java关键字。它没有“类型”
Travis Webb

它肯定不是同义词!void(小写)-关键字,未返回任何内容;Void(大写)-一个(不可实例化的)该类的实例被返回(只能是null因为不可实例化)
user85421 2011年

@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() {}
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.