RTTI(Run-Time Type Identification)运行时类别识别,在《Thinking in java》中提到其作用是在运行时识别一个对象的类型和类的信息。 主要有两种方式: 1. 传统的RTTI,它嘉定我们在编译时已经知道了所有的类型; 2. “反射”机制,运行在运行时发现和使用类的信息
Class类时一个实实在在的类,存在与JDK的java.lang包中,Class类的示例表示Java应用运行时的类(class ans enum)或接口(interface and annotation) (每个类运行时都在JVM里表现为一个class对象,可以通过类名.class、类型.getClass()、Class.forName(“类名”)等方法获取class对象).
数组同样也被映射为class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为 class 对象。
publicfinalclassClass<T> implementsjava.io.Serializable, GenericDeclaration, Type, AnnotatedElement{ privatestaticfinalint ANNOTATION = 0x00002000; privatestaticfinalint ENUM = 0x00004000; privatestaticfinalint SYNTHETIC = 0x00001000; privatestaticnativevoidregisterNatives(); static { registerNatives(); } /* * Private constructor. Only the Java Virtual Machine creates Class objects. //私有构造器,只有JVM才能调用创建Class对象 * This constructor is not used and prevents the default constructor being * generated. */ privateClass(ClassLoader loader){ // Initialize final field for classLoader. The initialization value of non-null // prevents future JIT optimizations from assuming this final field is null. classLoader = loader; } //.......... }
// java.lang.ClassLoader protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { // 先获取锁 synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded // 如果已经加载了的话,就不用再加载了 Class<?> c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { // 双亲委托加载 if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader }
// 父类没有加载到时,再自己加载 if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name);
// this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }
// 首先肯定是 Class.newInstance @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 // newInstance() 其实相当于调用类的无参构造函数,所以,首先要找到其无参构造器 if (cachedConstructor == null) { if (this == Class.class) { // 不允许调用 Class 的 newInstance() 方法 thrownew 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); returnnull; } }); 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 returnnull; } }
for (int i = 0; i < a1.length; i++) { if (a1[i] != a2[i]) { returnfalse; } }
returntrue; } // sun.reflect.ReflectionFactory /** Makes a copy of the passed constructor. The returned constructor is a "child" of the passed one; see the comments in Constructor.java for details. */ public <T> Constructor<T> copyConstructor(Constructor<T> arg){ return langReflectAccess().copyConstructor(arg); } // java.lang.reflect.Constructor, copy 其实就是新new一个 Constructor 出来 Constructor<T> copy(){ // This routine enables sharing of ConstructorAccessor objects // among Constructor objects which refer to the same underlying // method in the VM. (All of this contortion is only necessary // because of the "accessibility" bit in AccessibleObject, // which implicitly requires that new java.lang.reflect // objects be fabricated for each reflective call on Class // objects.) if (this.root != null) thrownew IllegalArgumentException("Can not copy a non-root Constructor");
Constructor<T> res = new Constructor<>(clazz, parameterTypes, exceptionTypes, modifiers, slot, signature, annotations, parameterAnnotations); // root 指向当前 constructor res.root = this; // Might as well eagerly propagate this if already present res.constructorAccessor = constructorAccessor; return res; }
// return tmpConstructor.newInstance((Object[])null); // java.lang.reflect.Constructor @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) thrownew 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; } // sun.reflect.DelegatingConstructorAccessorImpl public Object newInstance(Object[] args) throws InstantiationException, IllegalArgumentException, InvocationTargetException { return delegate.newInstance(args); } // sun.reflect.NativeConstructorAccessorImpl public Object newInstance(Object[] args) throws InstantiationException, IllegalArgumentException, InvocationTargetException { // We can't inflate a constructor belonging to a vm-anonymous class // because that kind of class can't be referred to by name, hence can't // be found from the generated bytecode. if (++numInvocations > ReflectionFactory.inflationThreshold() && !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) { ConstructorAccessorImpl acc = (ConstructorAccessorImpl) new MethodAccessorGenerator(). generateConstructor(c.getDeclaringClass(), c.getParameterTypes(), c.getExceptionTypes(), c.getModifiers()); parent.setDelegate(acc); }