84

I am implementing a ResponseHandler for the apache HttpClient package, like so:

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

but I'd like for the handleResponse function to return nothing, i.e. void. Is this possible? The following does not compile, since void is not a valid Java type:

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

I suppose I could replace void with Void to return a Void object, but that's not really what I want. Question: is it possible to organize this callback situation in such a way that I can return void from handleResponse?

Travis Webb
  • 13,507
  • 6
  • 51
  • 101

6 Answers6

91

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.

ILMTitan
  • 10,147
  • 2
  • 26
  • 43
  • 1
    Arrgh - the pain of generics the issue is if lets say you define a return type of "Void" you must put in a "return(null);" the main reason to declare the return type of void is so you don't have to have a return statement, and can use an existing "void" method :) Part of the issue with Java Generics is the conflation of run-time type checking with the need for compile time code generation and "bookeeping" assistance. One needs "macros" and "templates" that offer convenience in writing code on the *language* side. – peterk Apr 09 '13 at 14:15
  • 6
    +1 To clarify, Void has been around since JDK1.1. It was originally created for use with Reflection but has a similar role in generics. – John McCarthy Aug 16 '13 at 16:30
  • @ILMTitan Could you please give any references to the documentation about "return null" statement in methods that defined to return Void? – Andriy Simonov Nov 25 '16 at 14:38
  • @andriy-simonov Methods with a return type of `void` do not have to return a value. Methods with a return type of `Object` or any subclass, such as `Void` do have to return a value (or not complete normally). The only value that can be assigned to `Void`, and therefor returned from a `Void` method, is `null`. – ILMTitan Jan 19 '18 at 16:30
67

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?

Peter Lawrey
  • 498,481
  • 72
  • 700
  • 1,075
  • 8
    i'd just prefer not to have to include a `return` statement in a function where I'm not returning anything, for cleanliness mostly. – Travis Webb Apr 06 '11 at 17:00
  • 8
    You could create an abstract wrapper which call you `void` method and returns `null` to hide this ugliness. – Peter Lawrey Apr 06 '11 at 18:00
  • 48
    +1 for reminding me that "any problem in computer science can be solved by adding a layer of indirection" – Travis Webb Apr 06 '11 at 18:05
  • @TravisWebb Looking at your specific need, just don't use generics at all and return `Object` type if it'll work – Chaitanya Feb 19 '20 at 11:52
10

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

Oleksandr
  • 5,446
  • 42
  • 52
Ken Chu
  • 121
  • 1
  • 3
1

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.

ykaganovich
  • 13,997
  • 7
  • 55
  • 90
mark-cs
  • 4,579
  • 21
  • 31
  • 4
    `void` is not a primitive, it's merely a java keyword. It has no "type" – Travis Webb Apr 06 '11 at 15:18
  • and it surely is not synonymous! `void` (lowercase) - keyword, nothing returned; `Void` (uppercase) - an (uninstantiable) **class**, instance of that class being returned (can only be `null` since uninstantiable) – user85421 Apr 06 '11 at 15:53
  • @Carlos Heuberger analogous any better for you ? – mark-cs Apr 07 '11 at 14:06
1

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.

Adrian Smith
  • 15,946
  • 11
  • 65
  • 89
  • 1
    Because with a return type of Object the compiler cannot guarantee that only null is returned. Expanding on Thomas' answer, try these: `static Void v() { return null; } ` `static Void n() { return "NotAllowed"; } ` `static Object o() { return "Allowed"; } ` – Nathan Niesen Jul 28 '17 at 17:59
0

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() {}
}
JTHouseCat
  • 435
  • 4
  • 4
Jon
  • 39