Void真的不可信吗?

Void的javadoc说:

Void类是一个不合理的占位符类,用于保存对表示Java关键字void的Class对象的引用。

但构造函数很简单:

private Void() {}

并且这段代码实例化一个Void

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

所以Void并不是无稽之谈。

有没有办法让Void真正无法实现?


让你的构造函数是私有的,并且没有任何其他可以被外部访问的构造函数使得类不可实例化。

但是,您无法避免使用Reflection API访问它。 使用反射,你可以做,通常不允许的。

但是,如果你真的想让你的类变得毫无意义,即使通过Reflection,你也可以从构造函数中throw一个Unchecked Exception。

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

在这种情况下,当您使用Constructor#newInstance()方法创建实例时,它将引发一个InvocationTargetException ,如@Alex在注释中引用的那样。

这里是Constructor#newInstance()方法的文档,它声明了要抛出的异常列表,其中一个是InvocationTargetException ,它说: -

抛出:
InvocationTargetException - 如果底层构造函数抛出异常。


Rohit非常正确地说,抛出一个异常对大多数用例来说“足够好”。 但是,它看起来好像有可能绕过即使使用sun.misc.Unsafe:

公共本地对象allocateInstance(Class cls)抛出InstantiationException

分配一个实例但不运行任何构造函数。 如果还没有初始化该类。

(请注意,我没有真正测试过这个工作)


Reflection API可以像这样打破各种“规则”,就像修改final字段一样。 有很多抱怨说它允许你打破Java的硬性规则,但事实就是这样。

如果没有反射(或@ StevenSchlansker的疯狂的Unsafe API在下面发布),它是不可能实例化的。 尽管允许反射,但是,这些解决方法将存在。

在Oracle自己的Reflection教程中,他们列出了优点和缺点。 这取决于你决定哪个更大。

另外,看到这个问题:什么是反思,它为什么有用?

链接地址: http://www.djcxy.com/p/47633.html

上一篇: Is Void really uninstantiable?

下一篇: How to loop over a Class attributes in Java?