Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Void really uninstantiable?

The javadoc for Void says:

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

but the constructor is simply:

private Void() {} 

and this code instantiates a Void:

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

So Void is not uninstantiable.

Would there have been a way to make Void truly uninstantiable?

like image 244
Bohemian Avatar asked Dec 27 '12 19:12

Bohemian


People also ask

What is difference between void and void?

The basic difference between both ( Void & void ) is that void is a primitive type while Void , a reference type that inherits from the Object . Although none of them has any possible values, both are of different types. The void (all lowercase) is the improper type used to refer to the value's absence.

How do you return a void type?

Generics. As shown above, in order to return from a method with the Void return type, we just have to return null. Moreover, we could have either used a random type (such as Callable<Integer>) and return null or no type at all (Callable), but using Void states our intentions clearly.

How do you return a void in Java?

You declare a method's return type in its method declaration. Within the body of the method, you use the return statement to return the value. Any method declared void doesn't return a value. It does not need to contain a return statement, but it may do so.


2 Answers

Rohit is quite right that throwing an exception is "good enough" for most use cases. However, it looks like it might be possible to bypass even that, using sun.misc.Unsafe:

public native Object allocateInstance(Class cls) throws InstantiationException

Allocate an instance but do not run any constructor. Initializes the class if it has not yet been.

(Note that I haven't actually tested that this works)

like image 182
Steven Schlansker Avatar answered Sep 19 '22 17:09

Steven Schlansker


Making your constructor private, and not having any other constructor that can be accessed by outside, makes a class un-instantiable.

However, you cannot avoid it from being accessed using Reflection API. Using reflection, you can do, what is not allowed normally.

But, if you really want your class to be uninstantiable, even through Reflection, you can throw an Unchecked Exception from the constructor.

private MyClass() {     throw UnsupportedOperationException("Can't instantiate class"); } 

In which case, when you create the instance using Constructor#newInstance() method, it will throw an InvocationTargetException, as quoted in comments by @Alex.

Here's the documentation of Constructor#newInstance() method, which declares a list of exception to be thrown, one of them is InvocationTargetException, and it says that: -

throws:
InvocationTargetException - if the underlying constructor throws an exception.

like image 24
Rohit Jain Avatar answered Sep 19 '22 17:09

Rohit Jain