9

What is the difference between an object of a Void type and that of an unbounded wildcard type in Java generics? I mean I understand the use of <?>, and also the use of Void in terms of reflection, but I was a bit intrigued when I saw the Java source code for

java.util.concurrent.AbstractExecutorService

and its method

public Future<?> submit(Runnable task) {
    ...
    RunnableFuture<Void> ftask = new TaskFor(task, null);
    ...
    return ftask;

where inside the method it uses a RunnableFuture<Void> instead of RunnableFuture<?>

can someone help me understand the reason behind this? Thanks

Jim
  • 161
  • 2
  • 10
  • 1
    The difference is that there is nothing the same about them. Not a real question. – user207421 Oct 18 '12 at 21:27
  • that's why I said I was confused. Could you please elaborate a little more? Just saying nothing the same doesn't really help. – Jim Oct 19 '12 at 03:08
  • @Jim I don't know why the comment I posted below is marked as deleted, but do you seriously see a Void keyword in the submit function of AbstractExecutorService? Because it's not there at least in JDK 6 source code. – Arham Oct 19 '12 at 04:03
  • @Arham I am pretty sure your comment is still there. Just found out that they changed this from JDK6 to JDK7 (which was what I was looking at -- see rolve's reply below) – Jim Oct 19 '12 at 17:26

3 Answers3

16

Void is a special class that is used to represent no return value. While there is nothing special about Void per se, it can't be (and never is) instantiated, so the only possible value for it is always null. It is used for two things:

  1. To say that a generic method or class has no return value.
  2. To represent the void return type in Java reflection using Void.TYPE. See How to determine by reflection if a Method returns 'void' for example.

So it is very different from a wildcard, which is no actual class but represents one specific, unknown type at compile time. At runtime, it is erased like every other generic type.


Regarding the submit method. Here are the two implementations from JDK 6:

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Object> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}

and JDK 7:

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}

As you can see, the type was changed to Void only in JDK 7, probably because it makes more sense conceptually. But since the interface of the method could not be changed (for compatibility reasons and because the method implements Future<?> submit(Runnable task) of the ExecutorService interface), the return type Future<?> stayed the same. That's my explanation.

Community
  • 1
  • 1
rolve
  • 10,083
  • 4
  • 55
  • 75
  • Thank you and yes, but I am still not quite sure why the submit() method returns a Future> instead of a Future – Jim Oct 19 '12 at 03:12
  • Thank you rolve, especially for posting JDK6 and JDK7 side by side, which made things more clear. So it seems more like a matter of what makes more sense rather than what's right and wrong. – Jim Oct 19 '12 at 17:25
4

Void isn't a wildcard, it represents that there is no value to return at all.

The Void javadoc...

Kevin Rubin
  • 587
  • 8
  • 17
  • Thank you. I understand the Void as what its javadoc says, but why doesn't the submit() method return a Future; instead of Future> ? – Jim Oct 19 '12 at 03:10
3

Void is the object representation of void. Where void returns nothing from a method, Void ALWAYS returns null. This is because void isn't an object and therefore cannot be used with Generics. It's nice to use Void with Futures when you don't need any return values.

Kurtymckurt
  • 337
  • 2
  • 6
  • Did you take a look at the source code? For returning void you just need a Runnable Interface and it's run method and not a Future with void. – Arham Oct 18 '12 at 19:58