returning a Void object

129,445

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.

Solution 5

It is possible to create instances of Void if you change the security manager, so something like this:

static Void getVoid() throws SecurityException, InstantiationException,
        IllegalAccessException, InvocationTargetException {
    class BadSecurityManager extends SecurityManager {
    
        @Override
        public void checkPermission(Permission perm) { }
    
        @Override
        public void checkPackageAccess(String pkg) { }

    }
    System.setSecurityManager(badManager = new BadSecurityManager());
    Constructor<?> constructor = Void.class.getDeclaredConstructors()[0];
    if(!constructor.isAccessible()) {
        constructor.setAccessible(true);
    }
    return (Void) constructor.newInstance();
}

Obviously this is not all that practical or safe; however, it will return an instance of Void if you are able to change the security manager.

Share:
129,445
Robert
Author by

Robert

Updated on July 19, 2022

Comments

  • Robert
    Robert almost 2 years

    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;
        }
    }
    
    • Robert
      Robert about 14 years
      i'm writing an interpreter for a file format, using the interpreter pattern, but some expressions don't have return values
    • Jorn
      Jorn about 14 years
      There's no way to instantiate the Void type, so if you really have to return something of that type, null is your only option. However, you probably don't need the returned value for anything, so null should be fine.
    • Robert
      Robert about 14 years
      yeah, that was my logic too - just wondered if there was a more semantic way
    • David Roussel
      David Roussel about 14 years
      I would code it up just like your example. That's a fine approach.
  • Robert
    Robert about 14 years
    then what is the generically correct way to achieve a return type of void?
  • Robert
    Robert about 14 years
    is this the convention for setting the return type to void with generics - it doesn't look very void to me?
  • Robert
    Robert about 14 years
    how is this different from what I already have? it still just returns null, like I suggested
  • Christopher Oezbek
    Christopher Oezbek about 14 years
    I believe this is the way to go. Any user of class A<?> will not be able to make any use of the returned value of method().
  • Jorn
    Jorn about 14 years
    Why would you have to return anything else? The point I'm trying to make is you don't need the return value, so it doesn't matter what you return. I tried to clarify that with my edit.
  • Patrick
    Patrick about 8 years
    If you want to return null as void you need to cast it in some cases: (Void) null
  • steinybot
    steinybot about 7 years
    My opinion is that this is going in the wrong direction. It is better to return a much more constrained type that conveys the meaning much clearer. Having something that returns an Optional<Void> is unnecessary for the same reason that you give, you always get an Optional<Void> that is empty and so all the other methods are pointless. This is the opposite of why an optional value should be used. You use it because it may or may not have a value. Also the compiler cannot enforce that method() implements it correctly. This would fail at runtime: return Optional.of(null).
  • Alex R
    Alex R over 4 years
    return (Void)null;
  • lue
    lue over 4 years
    can (Void)null be differentiated from null in any way?