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