Void真的无法实现吗?

时间:2012-12-27 19:22:31

标签: java reflection void

javadoc for Void说:

  

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

但构造函数只是:

private Void() {}

并且此代码实例化Void

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

所以Void 不可实现。

是否有办法让Void真正无法实现?

3 个答案:

答案 0 :(得分:29)

Rohit非常正确,对于大多数用例而言,抛出异常“足够好”。但是,看起来bypass even that, using sun.misc.Unsafe

似乎是可能的
  

公共本机Object allocateInstance(Class cls)抛出   InstantiationException

     

分配实例但不运行任何实例   构造函数。如果该类尚未初始化,则对其进行初始化。

(请注意,我实际上没有测试过这是否有效)

答案 1 :(得分:28)

使您的构造函数成为私有,并且没有任何其他可以被外部访问的构造函数,从而使类不可实例化

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

但是,如果您真的希望您的课程不可安装,即使通过 Reflection ,您也可以throw 未经检查的例外来自构造函数

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

在这种情况下,当您使用Constructor#newInstance()方法创建实例时,它将抛出InvocationTargetException,如@Alex的评论引用。

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

  

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

答案 2 :(得分:10)

Reflection API打破了这样的各种“规则”,就像能够修改final字段一样。有很多人抱怨它可以让你打破Java的严格规则,但事实就是如此。

如果没有反射(或下面发布的@ StevenSchlansker的疯狂Unsafe API),则无法实例化。但是,只要允许反射,这些变通方法就会存在。

Oracle's own Reflection tutorial中,他们列出了利弊。由你决定哪个更大。

另请参阅此问题:What is reflection and why is it useful?