What's the difference between Void and no parameter?

JavaVoid

Java Problem Overview


I have a class which defines two overloaded methods

public void handle(Void e) 

protected void handle() 

Obviously they are different, especially handle(Void e) is public.


What's the difference between those two?

How to call the first method? I am using handle(null) - is this correct?

Java Solutions


Solution 1 - Java

Void is a special class usually used only for reflection - its primary use is to represent the return type of a void method. From the javadoc for Void:

> The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword void.

Because the Void class can not be instantiated, the only value you can pass to a method with a Void type parameter, such as handle(Void e), is null.


That's the official version of events, but for those who are interested, despite claims to the contrary in the javadoc of Void, you can actually instantiate an instance of Void:

Constructor<Void> c = Void.class.getDeclaredConstructor();
c.setAccessible(true);
Void v = c.newInstance(); // Hello sailor!


That said, I have seen Void "usefully" used as a generic parameter type when you want to indicate that the type is being "ignored", for example:

Callable<Void> ignoreResult = new Callable<Void> () {
    public Void call() throws Exception {
        // do something
        return null; // only possible value for a Void type
    }
}

Callable's generic parameter is the return type, so when Void is used like this, it's a clear signal to readers of the code that the returned value is not important, even though the use of the Callable interface is required, for example if using the Executor framework.

Solution 2 - Java

The first function is a function of a single argument, which must be provided and can only validly take the value null. Any value other than null will not compile. The second function doesn't take any argument and passing null to it would not compile.

Solution 3 - Java

Consider the API to AsyncTask<T1, T2, T3> from the Android system, which provides three hooks:

class AsyncTask<S, T, V> {
  void doInBackground(S...);
  void onProgressUpdate(T...);
  void onPostExecute(V);
}

When you extend the generic type AsyncTask<T1, T2, T3> you may not be interested in using parameters for the progress and result hooks, so your implementation will look like:

class HTTPDownloader extends AsyncTask<URL, Void, Void> {
  void doInBackground(URL... urls) {}
  void onProgressUpdate(Void... unused) {}
  void onPostExecute(Void unused) {}
}

and you can invoke these methods with a null parameter, since Void can't be instantiated.

Solution 4 - Java

If Void isn't actually an instantiation of a type parameter (where it obviously makes sense), there is also sense in declaring a handle(Void) if your handle method is subject to an extralinguistic contract that says that the object that wants to participate in a certain protocol must implement a one-argument handle method, regardless of the actual argument type. Now, there may be a special-case implementation that can't handle anything but null so it makes sense to declare handle(Void) for such an implementation.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAdam LeeView Question on Stackoverflow
Solution 1 - JavaBohemianView Answer on Stackoverflow
Solution 2 - JavaConfusionView Answer on Stackoverflow
Solution 3 - JavaRaffaeleView Answer on Stackoverflow
Solution 4 - JavaMarko TopolnikView Answer on Stackoverflow