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?
The Reflection API breaks all kinds of "rules" like this, just like being able to modify
final
fields. There are many complaints about the fact that it allows you to break the hard and fast rules of Java, but that's how it is.Without Reflection (or @StevenSchlansker's crazy
Unsafe
API posted below), it's not possible to instantiate. As long as Reflection is allowed, though, these workarounds will exist.In Oracle's own Reflection tutorial, they list the benefits and drawbacks. It's up to you to decide which is greater.
Also, see this question: What is reflection and why is it useful?
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.In which case, when you create the instance using
Constructor#newInstance()
method, it will throw anInvocationTargetException
, 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 isInvocationTargetException
, and it says that: -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:
(Note that I haven't actually tested that this works)