Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the difference between Void and unbounded wildcard in Java generics?

Tags:

java

generics

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

like image 393
Jim Avatar asked Oct 18 '12 19:10

Jim


3 Answers

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.

like image 64
rolve Avatar answered Oct 23 '22 05:10

rolve


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

The Void javadoc...

like image 30
Kevin Rubin Avatar answered Oct 23 '22 06:10

Kevin Rubin


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.

like image 42
Kurtymckurt Avatar answered Oct 23 '22 06:10

Kurtymckurt