returning a Void object
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 returningnew Object()
ornull
- parameterizing with
Void
and returningnull
- 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.
Robert
Updated on July 19, 2022Comments
-
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 about 14 yearsi'm writing an interpreter for a file format, using the interpreter pattern, but some expressions don't have return values
-
Jorn about 14 yearsThere'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 about 14 yearsyeah, that was my logic too - just wondered if there was a more semantic way
-
David Roussel about 14 yearsI would code it up just like your example. That's a fine approach.
-
-
Robert about 14 yearsthen what is the generically correct way to achieve a return type of void?
-
Robert about 14 yearsis this the convention for setting the return type to void with generics - it doesn't look very void to me?
-
Robert about 14 yearshow is this different from what I already have? it still just returns null, like I suggested
-
Christopher Oezbek about 14 yearsI believe this is the way to go. Any user of class
A<?>
will not be able to make any use of the returned value ofmethod()
. -
Jorn about 14 yearsWhy 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 about 8 yearsIf you want to return null as void you need to cast it in some cases: (Void) null
-
steinybot about 7 yearsMy 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 anOptional<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 thatmethod()
implements it correctly. This would fail at runtime:return Optional.of(null)
. -
Alex R over 4 years
return (Void)null;
-
lue over 4 yearscan (Void)null be differentiated from null in any way?