通過Class.newInstance()和Constructor.newInstance()兩種反射方法建立物件的異同

NO IMAGE

首先兩種方式在原始碼裡所在的位置

Class.newInstance() → Inside java.lang 包
Constructor.newInstance() → Inside java.lang.reflect 包

使用方法

Class.newInstance():

Class.forName("HelloWorld").newInstance();

或者

HelloWorld.class.newInstance();

Constructor.newInstance()

HelloWorld.class.getConstructor().newInstance();

二者區別

Class.newInstance()只能反射無參的構造器;
Constructor.newInstance()可以反任何構造器;
Class.newInstance()需要構造器可見(visible);
Constructor.newInstance()可以反私有構造器;
Class.newInstance()對於捕獲或者未捕獲的異常均由構造器丟擲;
Constructor.newInstance()通常會把丟擲的異常封裝成InvocationTargetException丟擲;

因為以上差異,所以很多框架使用的都是構造器反射的方式獲取物件,像Spring, Guava, Zookeeper, Jackson, Servlet 等。

原始碼:

version:jdk1.8

直接類名反射例項化物件

@CallerSensitive
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
}
// NOTE: the following code may not be strictly correct under
// the current Java memory model.
// Constructor lookup
if (cachedConstructor == null) {
if (this == Class.class) {
throw new IllegalAccessException(
"Can not call newInstance() on the Class for java.lang.Class"
);
}
try {
Class<?>[] empty = {};
final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
// Disable accessibility checks on the constructor
// since we have to do the security check here anyway
// (the stack depth is wrong for the Constructor's
// security check to work)
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
c.setAccessible(true);
return null;
}
});
cachedConstructor = c;
} catch (NoSuchMethodException e) {
throw (InstantiationException)
new InstantiationException(getName()).initCause(e);
}
}
Constructor<T> tmpConstructor = cachedConstructor;
// Security check (same as in java.lang.reflect.Constructor)
int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
}
}
// Run constructor
try {
return tmpConstructor.newInstance((Object[])null);
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// Not reached
return null;
}
}

反射構造器例項化物件:

@CallerSensitive
public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, null, modifiers);
}
}
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
ConstructorAccessor ca = constructorAccessor;   // read volatile
if (ca == null) {
ca = acquireConstructorAccessor();
}
@SuppressWarnings("unchecked")
T inst = (T) ca.newInstance(initargs);
return inst;
}