java - newInstance 类传播已检查和未检查的异常 - 这是真的吗?

标签 java

据此:https://docs.oracle.com/javase/tutorial/reflect/member/ctorTrouble.html

Class.newInstance() Throws Unexpected Exception The ConstructorTroubleToo example shows an unresolvable problem in Class.newInstance(). Namely, it propagates any exception — checked or unchecked — thrown by the constructor.

This situation is unique to reflection. Normally, it is impossible to write code which ignores a checked exception because it would not compile. It is possible to wrap any exception thrown by a constructor by using Constructor.newInstance() rather than 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();
    }

最佳答案

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

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

如果构造函数抛出异常,通过 Constructor.newInstance() 调用构造函数会将“真实”异常包装在 InitationTargetException 中并抛出该异常。但是,Class.newInstance() 并未声明抛出 InvocabularyTargetException,因此它捕获 Constructor.newInstance() 抛出的 InvocableTargetException 并抛出“真正的”异常相反,使用Unsafe.throwException()

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

关于java - newInstance 类传播已检查和未检查的异常 - 这是真的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30006312/

相关文章:

java - 为什么 Admob 横幅广告不向我展示? [Android,libGDX]

java - 未找到 Maven 模块项目

java - 无法解决或者不是eclipse中android中的字段错误

java - AVL树高度方法堆栈溢出错误

java - Spring Boot - MongoDB - MongoLab 配置

Java 反射 - 找不到 Android 类

java - 在路径 ""src/test/resources/上找不到文件”

java - 如何通过深度链接传递数据?

java - 在一行中设置另一个属性后返回一个对象

java - 学生/研究生项目中的经理类(class)问题