Java 类newInstance传播已检查和未检查的异常-是否为真?

Java 类newInstance传播已检查和未检查的异常-是否为真?,java,Java,据此: Class.newInstance()引发意外异常 ConstructorRoubleToo示例显示Class.newInstance()中存在无法解决的问题。也就是说,它传播构造函数抛出的任何已检查或未检查的异常 这种情况是反思所特有的。通常,不可能编写忽略已检查异常的代码,因为它不会编译。可以使用constructor.newInstance()而不是Class.newInstance()包装构造函数引发的任何异常 下面我有一段代码,它没有捕获任何未检查的(RuntimeEcxept

据此:

Class.newInstance()引发意外异常 ConstructorRoubleToo示例显示Class.newInstance()中存在无法解决的问题。也就是说,它传播构造函数抛出的任何已检查或未检查的异常

这种情况是反思所特有的。通常,不可能编写忽略已检查异常的代码,因为它不会编译。可以使用constructor.newInstance()而不是Class.newInstance()包装构造函数引发的任何异常

下面我有一段代码,它没有捕获任何未检查的(RuntimeEcxeption/Error)异常,我对它们进行了注释并编译了它。那么传播在哪里呢?我编写的代码忽略了未检查的异常,这些异常被告知是不可能的。请解释一下Class.newInstance()在上述引用方面有什么问题

try {
        Class<?> c = Class.forName("ConstructorTroubleToo");
        // Method propagetes any exception thrown by the constructor
        // (including checked exceptions).

        Object o = c.newInstance();

        // production code should handle these exceptions more gracefully
    } catch (ClassNotFoundException | 
            InstantiationException | 
            IllegalAccessException  x
           /*IllegalArgumentException | 
             SecurityException x*/ ) {
        x.printStackTrace();
    }
试试看{
c类=Class.forName(“构造函数也有问题”);
//方法传播构造函数引发的任何异常
//(包括已检查的例外情况)。
对象o=c.newInstance();
//生产代码应该更优雅地处理这些异常
}catch(ClassNotFoundException |
实例化异常|
IllegalacessException x
/*非法辩论例外|
安全性异常x*/){
x、 printStackTrace();
}

传播意味着异常只会消失,不像包装到InvocationTargetException中一样,反射方法通常会表现出来

实际上,编写忽略选中异常的代码并不是不可能的。从第一个案例考虑:

公共类测试{
//这里没有条款
公共静态void main(字符串[]args){
doThrow(新的SQLException());
}
静态空位点箭头(例外e){
测试doThrow0(e);
}
@抑制警告(“未选中”)
静止的
void doThrow0(异常e)抛出e{
投掷(E)E;
}
}
JVM不区分已检查和未检查的异常,有一些方法可以愚弄Java编译器。

Class.newInstance()
确实会传播它调用的、已检查或未检查的构造函数引发的任何异常。通过调用方法
sun.misc.Unsafe.throwException()
,以一种相当隐蔽的方式进行传播。这个方法只是抛出您给它的异常,它是类
sun.misc.Unsafe
的一部分,该类包含用于Java中低级“不安全”操作的各种方法。总结了其中的一些方法

JDK中有一个
src.zip
文件,其中包含一些标准Java平台类的源代码。特别是,您可以在这个zip文件
java/lang/Class.java
中找到
java.lang.Class
的源代码。打开此文件并查看其中的
newInstance()
方法。您会发现
Class.newInstance()
实际上使用
Constructor.newInstance()
来创建对象

如果构造函数引发异常,则通过
constructor.newInstance()
调用构造函数会将“真实”异常包装在InvocationTargetException中并引发该异常。但是,
Class.newInstance()
未声明引发InvocationTargetException,因此它会捕获构造函数.newInstance()引发的InvocationTargetException,并使用
不安全的.throweException()
引发“真实”异常


Class.newInstance()
没有声明为抛出InvocationTargetException的原因是因为该方法可以追溯到Java 1.0。InvocationTargetException和反射API的其余部分在1.1版中引入Java。添加
会将InvocationTargetException
抛出到
Class.newInstance()
中,这会破坏使用Java 1.1编译Java 1.0代码时的向后兼容性。

这是一个很好的技巧,但参考引文,为什么他们会说该类是“一个无法解决的问题”。newInstance()“传播构造函数抛出的任何异常(已检查或未检查)?这正是其他方法的工作方式,如果它们抛出RuntimeException,我们无法捕获它,如果是checkedException,我们捕获它,这有什么问题?他们希望它如何工作?我想我现在看到了,在某些构造函数中,我抛出了新异常();,通常我不会在没有try+catch的情况下用这样的构造函数编写新类,class.newInstance隐藏了这个异常,我甚至无法捕获它,constructor.newInstance包装到InvocationTargetException中,所以它比class.newInstance更好,因为我可以控制这种情况。是这样还是有其他原因?
public class Test {
    // No throws clause here
    public static void main(String[] args) {
        doThrow(new SQLException());
    }

    static void doThrow(Exception e) {
        Test.<RuntimeException> doThrow0(e);
    }

    @SuppressWarnings("unchecked")
    static <E extends Exception> 
    void doThrow0(Exception e) throws E {
        throw (E) e;
    }
}