39

I didn't even know this was doable, but I saw while perusing some code online a method with a signature like this:

public List<Void> read( ... )

... What? Is there ever a reason to do this? What could this List even hold? As far as I was aware, it's not possible to instantiate a Void object.

Roman C
  • 49,761
  • 33
  • 66
  • 176
asteri
  • 11,402
  • 13
  • 60
  • 84
  • 1
    Didn't the place where you saw the code explains it? I can't find any purpose for it right now. – Pablo Nov 22 '12 at 20:25
  • 2
    http://docs.oracle.com/javase/6/docs/api/java/lang/Void.html – Cory Kendall Nov 22 '12 at 20:26
  • I used to use it in [`SwingWorker`](http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html) and [`AsyncTask`](http://developer.android.com/reference/android/os/AsyncTask.html). – Eng.Fouad Nov 22 '12 at 20:29
  • I asked the [same question](http://stackoverflow.com/q/11968789/894284) for the Haskell version recently. Basically, a type inhabited by 0 values can be used to provide more guarantees through a static type system. However, `null` kind of defeats this. – Matt Fenwick Nov 27 '12 at 20:31

4 Answers4

26

It is possible that this method signature was created as a by-product of some generic class.

For example, SwingWorker has two type parameters, one for final result and one for intermediate results. If you just don't want to use any intermediate results, you pass Void as the type parameter, resulting in some methods returning Void - i.e. nothing.

If there were a method List<V> returnAllIntermediateResults() in SwingWorker with Void as the type parameter V, it would have created a method just like you posted in your question.

The code would be perfectly valid. You can instantiate any implementation of the List interface (e.g. ArrayList) with type parameter Void. But the only value a Void type can have is null. So the list could not hold anything else but nulls, if the implementation allows null elements.

Jakub Zaverka
  • 8,816
  • 3
  • 32
  • 48
  • 1
    I see. Very interesting! This is likely what I saw. Talk about crazy by products. – asteri Nov 22 '12 at 20:31
  • 1
    Good answer, but you can technically create an instance of Void through reflection. I have no idea why you'd ever want to do that though. – Dunes Nov 22 '12 at 20:46
  • 3
    @Jeff I don't like Void type very much. Usually when I see it, it means some advanced incomprehensible type wizardry is going on. The only 'reasoneable' use I saw was with the SwingWorker. – Jakub Zaverka Nov 22 '12 at 20:46
  • 1
    The `Void` type is often used for callback mechanisms accepting generic types and one of them being the return type. This can be `Void` if the function or callback returns nothing. For example, Android's `AsyncTask` accepts as third generic parameter the type of the `Result`. This could theoretically be anything, because it is not used anyways, but the type `Void` is often used to make its purpose clear. – MC Emperor Nov 01 '17 at 10:28
12

One case in which it may be useful is if you wanted to return a collection of return values from a function. Say

static List<T> forEach(Func<A,T> func, List<A> items) {
   List<T> ret = new List<T>();
   for(int i = 0; i< items.length; i++) {
     ret.add(func.call(items[i]);
   }
   return ret;
}

public static void main() {
  ...
  List<Void> boringResult = 
   forEach(
    new Func<Void, Integer> {@override Void call(Integer i) {...}});
}

Not that useful but you could see a case where it was required.

David Waters
  • 11,979
  • 7
  • 41
  • 76
  • 1
    Huh. Talk about a fringe case. Thanks for your answer! Very interesting. – asteri Nov 22 '12 at 20:43
  • Add `java.concurrent.Future` and `Callable` to the list. There a `Void` return type is not uncommon. – A.H. Nov 22 '12 at 23:33
  • The only possible return value from `Void call(Integer i) {...}` is `null`, since (according to [the docs](http://docs.oracle.com/javase/6/docs/api/java/lang/Void.html)): _"The Void class is an **uninstantiable** placeholder class"_ (emphasis added). I'm not sure how useful it is to construct a list that can only contain `null` references. – Ted Hopp Nov 23 '12 at 16:46
  • 1
    @TedHopp - Agreed, but if you are using a generic function such as the forEach above it may be easier to support that then disallow or create another overload. – David Waters Nov 24 '12 at 18:50
9

List<Void> is weird. It can only have null elements, since you can't create an object of type Void. I don't think there is a practical use for such a thing.

Void is part of java.lang. It's not a special keyword or anything. It's a "pseudo-type" (according to the docs) used to as a place-holder to represent the Class object corresponding to void, as in Class<Void>. From the docs for Class:

The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.

The Void class exists mainly for the sake of the last part of this, so you can write:

Class<Void> voidType = void.class; // == Void.TYPE

just like you can write:

Class<Integer> intType = int.class; // == Integer.TYPE
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
4

I agree, it's odd.

I can see a use for it if you want to extend a generic class and return void from a method. I've bumped into a case were I want to use int and had to use Integer because java generics don't like primitive types.

public interface ObjectUserPool<E, T> {
    public E useObject(T o);
}

public class NonReturningObjectUserPool extends ObjectUserPool<Void, Integer> {
    public Void useObject(Integer i);
}

I think this is what the java API is saying, though to be honest I can't really find a use for NonReturningObjectUserPool.

Cory Kendall
  • 7,195
  • 8
  • 37
  • 64
  • 1
    You can return `null` for any reference type; it doesn't require anything special like `Void`. – Ted Hopp Nov 22 '12 at 20:36
  • 1
    @TedHopp good point, answer edited. I think it's still valid to want to return void to be self documenting; rather than claiming to return Integer and then internally always returning null, and claiming in javadoc that you always return null or something. – Cory Kendall Nov 22 '12 at 20:38