Class.newInstance方法
Parent parent = (Parent) Class.forName("Parent").newInstance();
Parent parent = (Parent) Class.forName("Parent").newInstance();
newInstance方法是一个弱类型的方法,它只能调用无参构造方法,而且再调用这个方法之前,必须保证
1、这个类已经加载
2、这个类已经连接了
而这两步都在前面Class.forName方法实现了。
public static Class<?> forName(String className)
throws ClassNotFoundException {
return forName0(className, true,
ClassLoader.getClassLoader(Reflection.getCallerClass()));
}
private static native Class<?> forName0(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException;
public static Class<?> forName(String className)
throws ClassNotFoundException {
return forName0(className, true,
ClassLoader.getClassLoader(Reflection.getCallerClass()));
}
private static native Class<?> forName0(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException;
由native关键字标识的forName0方法通过JNI调用实现了。这里就不深入研究了。大约是将类名,与JVM的类加载器都提供过去,对类对象进行初始化,分配内存空间,初始化静态内容.
而在newInstance()方法中
public T newInstance()
throws InstantiationException, IllegalAccessException
{
//获取JAVA的安全管理器re
//JAVA的安全管理器可参考这里 http://blog.ticeng.com/462.html
if (System.getSecurityManager() != null) {
/*关于checkMemberAccess 函数
* Check if client is allowed to access members. If access is denied,
* throw a SecurityException.
*
* This method also enforces package access.
*
* <p> Default policy: allow all clients access with normal Java access
* control.
*/
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
}
// NOTE: the following code may not be strictly correct under
// the current Java memory model.
// Constructor lookup
/*此处cachedConstructor定义为
*private volatile transient Constructor<T> cachedConstructor;
*即为JAVA的构造器,再从名字上来看应该指的是内存中的构造器。详细信息就不知道了。希望大神指点。
*/
if (cachedConstructor == null) {
//这里再做了一个判断,根据输出的错误信息判断,应该是不能够加载Class.class这个class文件
if (this == Class.class) {
throw new IllegalAccessException(
"Can not call newInstance() on the Class for java.lang.Class"
);
}
try {
Class<?>[] empty = {};
/*在getConstructor0方法中做了这些工作为了获得无参构造器对象。
* Member.DECLARED的值为1,表示 标识类或接口的所有已声明成员的集合。
* 通过内部privateGetDeclaredConstructors 方法获取所有的构造函数对象。
* 然后再遍历得到其无参构造器对象
* PS:这些是根据源码和一些资料的猜测,不保证正确性。
*/
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)
//通过JNI调用
//
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
//setAccessible值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查,来提高反射速度?
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();
//用Reflection的quickCheckMemberAccess方法先检查是不是public的
//如果不是再用Reflection.getCallerClass()方法获得到调用这个方法的Class,然后做是否有权限访问的校验,
//即当前调用的类是否有权限访问需要实例化的类
//校验之后缓存一次,以便下次如果还是这个类来调用就不用去做校验了,直接用上次的结果。
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
}
}
// Run constructor
try {
//在Constructor的newInstance方法中
/*public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
{
//关于override字段
// Indicates whether language-level access checks are overridden
// by this object. Initializes to "false". This field is used by
// Field, Method, and Constructor.
//
// NOTE: for security purposes, this field must not be visible
// outside this package.
*
if (!override) {
//再次检查是否为public
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
//caller 表示调用这个方法的类,此处应该指的是调用实例化方法的类,即当前线程的类
//clazz 表示 声明了 由构造器函数代表的构造函数的 类, 即要实例化的类对象。
//从所抛出的异常和源码注释分析,此处是检查该类的构造函数是否能够被访问到。
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")
//此处ca 的最终可能为DelegatingConstructorAccessorImpl 的一个实例
//其newInstance方法调用了继承了ConstructorAccessorImpl的NativeConstructorAccessorImpl的newInstance方法。
//我忍不住又要贴源码了
// public Object newInstance(Object[] args) throws InstantiationException, IllegalArgumentException, InvocationTargetException {
// //此处numInvocations 找不到初始化赋值的地方
// if (++numInvocations > ReflectionFactory.inflationThreshold()) {
// ConstructorAccessorImpl acc = (ConstructorAccessorImpl)
// new MethodAccessorGenerator().
// generateConstructor(c.getDeclaringClass(),
// c.getParameterTypes(),
// c.getExceptionTypes(),
// c.getModifiers());
// //传递一个ConstructorAccessorImpl实例回去?
// parent.setDelegate(acc);
// }
//
// return newInstance0(c, args);
// }
// //调用JNI方法生成实例
// private static native Object newInstance0(Constructor c, Object[] args)
// throws InstantiationException,
// IllegalArgumentException,
// InvocationTargetException;
T inst = (T) ca.newInstance(initargs);
return inst;
}*/
return tmpConstructor.newInstance((Object[])null);
//至此,对象已经被成功的实例化出来了。
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// Not reached
return null;
}
}
public T newInstance()
throws InstantiationException, IllegalAccessException
{
//获取JAVA的安全管理器re
//JAVA的安全管理器可参考这里 http://blog.ticeng.com/462.html
if (System.getSecurityManager() != null) {
/*关于checkMemberAccess 函数
* Check if client is allowed to access members. If access is denied,
* throw a SecurityException.
*
* This method also enforces package access.
*
* <p> Default policy: allow all clients access with normal Java access
* control.
*/
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
}
// NOTE: the following code may not be strictly correct under
// the current Java memory model.
// Constructor lookup
/*此处cachedConstructor定义为
*private volatile transient Constructor<T> cachedConstructor;
*即为JAVA的构造器,再从名字上来看应该指的是内存中的构造器。详细信息就不知道了。希望大神指点。
*/
if (cachedConstructor == null) {
//这里再做了一个判断,根据输出的错误信息判断,应该是不能够加载Class.class这个class文件
if (this == Class.class) {
throw new IllegalAccessException(
"Can not call newInstance() on the Class for java.lang.Class"
);
}
try {
Class<?>[] empty = {};
/*在getConstructor0方法中做了这些工作为了获得无参构造器对象。
* Member.DECLARED的值为1,表示 标识类或接口的所有已声明成员的集合。
* 通过内部privateGetDeclaredConstructors 方法获取所有的构造函数对象。
* 然后再遍历得到其无参构造器对象
* PS:这些是根据源码和一些资料的猜测,不保证正确性。
*/
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)
//通过JNI调用
//
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
//setAccessible值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查,来提高反射速度?
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();
//用Reflection的quickCheckMemberAccess方法先检查是不是public的
//如果不是再用Reflection.getCallerClass()方法获得到调用这个方法的Class,然后做是否有权限访问的校验,
//即当前调用的类是否有权限访问需要实例化的类
//校验之后缓存一次,以便下次如果还是这个类来调用就不用去做校验了,直接用上次的结果。
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
}
}
// Run constructor
try {
//在Constructor的newInstance方法中
/*public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
{
//关于override字段
// Indicates whether language-level access checks are overridden
// by this object. Initializes to "false". This field is used by
// Field, Method, and Constructor.
//
// NOTE: for security purposes, this field must not be visible
// outside this package.
*
if (!override) {
//再次检查是否为public
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
//caller 表示调用这个方法的类,此处应该指的是调用实例化方法的类,即当前线程的类
//clazz 表示 声明了 由构造器函数代表的构造函数的 类, 即要实例化的类对象。
//从所抛出的异常和源码注释分析,此处是检查该类的构造函数是否能够被访问到。
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")
//此处ca 的最终可能为DelegatingConstructorAccessorImpl 的一个实例
//其newInstance方法调用了继承了ConstructorAccessorImpl的NativeConstructorAccessorImpl的newInstance方法。
//我忍不住又要贴源码了
// public Object newInstance(Object[] args) throws InstantiationException, IllegalArgumentException, InvocationTargetException {
// //此处numInvocations 找不到初始化赋值的地方
// if (++numInvocations > ReflectionFactory.inflationThreshold()) {
// ConstructorAccessorImpl acc = (ConstructorAccessorImpl)
// new MethodAccessorGenerator().
// generateConstructor(c.getDeclaringClass(),
// c.getParameterTypes(),
// c.getExceptionTypes(),
// c.getModifiers());
// //传递一个ConstructorAccessorImpl实例回去?
// parent.setDelegate(acc);
// }
//
// return newInstance0(c, args);
// }
// //调用JNI方法生成实例
// private static native Object newInstance0(Constructor c, Object[] args)
// throws InstantiationException,
// IllegalArgumentException,
// InvocationTargetException;
T inst = (T) ca.newInstance(initargs);
return inst;
}*/
return tmpConstructor.newInstance((Object[])null);
//至此,对象已经被成功的实例化出来了。
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// Not reached
return null;
}
}
class 类的 newInstance方法的流程应该基本就在上面了,每一步函数步骤都加上了一些分析,如果还有什么不足或者错误的地方希望大家指出。