returning a Void object

What is the correct way to return a Void type, when it isn't a primitive? Eg. I currently use null as below.

interface B<E>{ E method(); }

class A implements B<Void>{

    public Void method(){
        // do something
        return null;
    }
}

Solution 1:

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

So any of the following would suffice:

  • parameterizing with Object and returning new Object() or null
  • parameterizing with Void and returning null
  • parameterizing with a NullObject of yours

You can't make this method void, and anything else returns something. Since that something is ignored, you can return anything.

Solution 2:

Java 8 has introduced a new class, Optional<T>, that can be used in such cases. To use it, you'd modify your code slightly as follows:

interface B<E>{ Optional<E> method(); }

class A implements B<Void>{

    public Optional<Void> method(){
        // do something
        return Optional.empty();
    }
}

This allows you to ensure that you always get a non-null return value from your method, even when there isn't anything to return. That's especially powerful when used in conjunction with tools that detect when null can or can't be returned, e.g. the Eclipse @NonNull and @Nullable annotations.

Solution 3:

If you just don't need anything as your type, you can use void. This can be used for implementing functions, or actions. You could then do something like this:

interface Action<T> {
    public T execute();
}

abstract class VoidAction implements Action<Void> {
    public Void execute() {
        executeInternal();
        return null;
    }

    abstract void executeInternal();
}

Or you could omit the abstract class, and do the return null in every action that doesn't require a return value yourself.

You could then use those actions like this:

Given a method

private static <T> T executeAction(Action<T> action) {
    return action.execute();
}

you can call it like

String result = executeAction(new Action<String>() {
    @Override
    public String execute() {
        //code here
        return "Return me!";
    }
});

or, for the void action (note that you're not assigning the result to anything)

executeAction(new VoidAction() {
    @Override
    public void executeInternal() {
        //code here
    }
});

Solution 4:

Just for the sake of it, there is of course the possibility to create Void instance using reflection:

interface B<E>{ E method(); }

class A implements B<Void>{

    public Void method(){
        // do something

        try {
            Constructor<Void> voidConstructor = Void.class.getDeclaredConstructor();
            voidConstructor.setAccessible(true);
            return voidConstructor.newInstance();
        } catch (Exception ex) {
            // Rethrow, or return null, or whatever.
        }
    }
}

You probably won't do that in production.