Java 泛型 Void/Void 类型

我正在为 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

67919 次浏览

You can't have primitives in generics so that int is actually an Integer. The object Void is analogous with the keyword void for generics.

Alas it's not possible. You can set the code to return Void as you say, however you can never instanciate a Void so you can't actually write a function which conforms to this specification.

Think of it as: The generic function says "this function returns something, of type X", and you can specify X but you can't change the sentence to "this function returns nothing". (I'm not sure if I agree with these semantics, but that's the way they are.)

In this case, what I always do, is just make the function return type Object, and in fact always return null.

Generics only handles object classes. void and primitive types are not supported by Generics and you cannot use these as a parameterized type. You have to use Void instead.

Can you say why you don't want to use Void?

The Void type was created for this exact situation: to create a method with a generic return type where a subtype can be "void". Void was designed in such a way that no objects of that type can possibly be created. Thus a method of type Void will always return null (or complete abnormally), which is as close to nothing as you are going to get. You do have to put return null in the method, but this should only be a minor inconvenience.

In short: Do use Void.

This java.lang.Void implementation in Java kind of speaks for itself. Also, I wrote an article that ties this into generics. It took a bit of thought before I started understanding this: http://www.siteconsortium.com/h/D00006.php. Notice TYPE = Class.getPrimitiveClass("void");

package java.lang;

public final class Void {


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


private Void() {}
}

When you need to return java.lang.Void, just return null.