我们先看一下官方说明
* @deprecated This method propagates any exception thrown by the
* nullary constructor, including a checked exception. Use of
* this method effectively bypasses the compile-time exception
* checking that would otherwise be performed by the compiler.
* The {@link
* java.lang.reflect.Constructor#newInstance(java.lang.Object...)
* Constructor.newInstance} method avoids this problem by wrapping
* any exception thrown by the constructor in a (checked) {@link
* java.lang.reflect.InvocationTargetException}.
大致意思是:
class.newInstance()方法传播由空构造函数引发的任何异常,包括已检查的异常。
这种方法的使用有效地绕过了编译时异常检查,否则该检查将由编译器执行。
clazz.newInstance()方法由clazz.getDeclaredConstructor().newInstance()方法代替,该方法通过将构造函数抛出的任何异常包装在(InvocationTargetException)中来避免此问题。
也就是说使用class.newInstance()方法时由默认构造函数中抛出的异常,此方法检查不到,如下例子:
public class ClassInstanceTest {
public ClassInstanceTest() throws IOException {
System.out.println("无参构造");
throw new IOException();
}
public static void main(String[] args) {
try {
ClassInstanceTest classInstanceTest = ClassInstanceTest.class.newInstance();
} catch (InstantiationException e) {
System.out.println("InstantiationException");
e.printStackTrace();
} catch (IllegalAccessException e) {
System.out.println("IllegalAccessException");
e.printStackTrace();
}
}
}
运行输出:
无参构造
Exception in thread "main" java.io.IOException
at ClassInstanceTest.<init>(ClassInstanceTest.java:9)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:166)
at java.base/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:404)
at java.base/java.lang.Class.newInstance(Class.java:590)
at ClassInstanceTest.main(ClassInstanceTest.java:14)
我们看到,没有被异常检查捕获到吧。
接下来我们使用clazz.getDeclaredConstructor().newInstance()方法:
public class ClassInstanceTest {
public ClassInstanceTest() throws IOException {
System.out.println("无参构造");
throw new IOException();
}
public static void main(String[] args) {
try {
Class clazz = ClassInstanceTest.class;
clazz.getDeclaredConstructor().newInstance();
} catch (InstantiationException e) {
System.out.println("InstantiationException");
e.printStackTrace();
} catch (IllegalAccessException e) {
System.out.println("IllegalAccessException");
e.printStackTrace();
} catch (InvocationTargetException e) {
System.out.println("InvocationTargetException");
e.printStackTrace();
} catch (NoSuchMethodException e) {
System.out.println("NoSuchMethodException");
e.printStackTrace();
}
}
}
运行输出:
无参构造
InvocationTargetException
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
at ClassInstanceTest.main(ClassInstanceTest.java:15)
Caused by: java.io.IOException
at ClassInstanceTest.<init>(ClassInstanceTest.java:9)
... 6 more
可以看到被InvocationTargetException异常捕获到了。