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
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:
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.
Void isn't a wildcard, it represents that there is no value to return at all.
The Void javadoc...
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With