RRIT(Run-Time Type Identification)运行时类型识别。在《Thinking in Java》一书第十四章中有提到,其作用是**在运行时识别一个对象的类型和类的信息。**主要有两种方式:一种是“传统的”RTTI,它假定我们在编译时已经知道了所有的类型;另一种是“反射”机制,它允许我们在运行时发现和使用类的信息。
Class类,Class类也是一个实实在在的类,存在于JDK的java.lang包中。Class类的实例表示java应用运行时的类(class ans enum)或接口(interface and annotation)(每个java类运行时都在JVM里表现为一个class对象,可通过类名.class、类型.getClass()、Class.forName("类名")等方法获取class对象)。数组同样也被映射为为class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为 class 对象。
某种意义上来说,Java有两种对象:实例对象和Class对象。
每个类的运行时的类型信息就是用Class对象表示的。它包含了与类有关的信息。
我们的实例对象就通过Class对象来创建的。Java使用Class对象执行其RTTI(运行时类型识别,Run-Time Type Identification),多态是基于RTTI实现的。
publicfinalclassClass<T> implements java.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; }
// publicClass<?>loadClass(String name) throws ClassNotFoundException {returnloadClass(name,false); }// sun.misc.LauncherpublicClass<?>loadClass(String var1,boolean var2) throws ClassNotFoundException {int var3 =var1.lastIndexOf(46);if(var3 !=-1) {SecurityManager var4 =System.getSecurityManager();if(var4 !=null) {var4.checkPackageAccess(var1.substring(0, var3)); } }if(this.ucp.knownToNotExist(var1)) {Class var5 =this.findLoadedClass(var1);if(var5 !=null) {if(var2) {this.resolveClass(var5); }return var5; } else {thrownewClassNotFoundException(var1); } } else {return super.loadClass(var1, var2); } }// java.lang.ClassLoaderprotectedClass<?>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 statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment(); } }if (resolve) {resolveClass(c); }return c; } }protectedObjectgetClassLoadingLock(String className) {Object lock =this;if (parallelLockMap !=null) {// 使用 ConcurrentHashMap来保存锁Object newLock =newObject(); lock =parallelLockMap.putIfAbsent(className, newLock);if (lock ==null) { lock = newLock; } }return lock; }protectedfinalClass<?>findLoadedClass(String name) {if (!checkName(name))returnnull;returnfindLoadedClass0(name); }
下面来看一下 newInstance() 的实现方式。
// 首先肯定是 Class.newInstance @CallerSensitivepublicTnewInstance() 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() 方法thrownewIllegalAccessException("Can not call newInstance() on the Class for java.lang.Class" ); }try {// 获取无参构造器Class<?>[] empty = {};finalConstructor<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(newjava.security.PrivilegedAction<Void>() {publicVoidrun() {c.setAccessible(true);returnnull; } }); cachedConstructor = c; } catch (NoSuchMethodException e) {throw (InstantiationException)newInstantiationException(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 constructortry {// 调用无参构造器returntmpConstructor.newInstance((Object[])null); } catch (InvocationTargetException e) {Unsafe.getUnsafe().throwException(e.getTargetException());// Not reachedreturnnull; } }
// reflection data that might get invalidated when JVM TI RedefineClasses() is calledprivatestaticclassReflectionData<T> {volatileField[] declaredFields;volatileField[] publicFields;volatileMethod[] declaredMethods;volatileMethod[] publicMethods;volatileConstructor<T>[] declaredConstructors;volatileConstructor<T>[] publicConstructors;// Intermediate results for getFields and getMethodsvolatileField[] declaredPublicFields;volatileMethod[] declaredPublicMethods;volatileClass<?>[] interfaces;// Value of classRedefinedCount when we created this ReflectionData instancefinalint redefinedCount;ReflectionData(int redefinedCount) {this.redefinedCount= redefinedCount; } }
privatestaticbooleanarrayContentsEq(Object[] a1,Object[] a2) {if (a1 ==null) {return a2 ==null||a2.length==0; }if (a2 ==null) {returna1.length==0; }if (a1.length!=a2.length) {returnfalse; }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) {returnlangReflectAccess().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)thrownewIllegalArgumentException("Can not copy a non-root Constructor");Constructor<T> res =newConstructor<>(clazz, parameterTypes, exceptionTypes, modifiers, slot, signature, annotations, parameterAnnotations);// root 指向当前 constructorres.root=this;// Might as well eagerly propagate this if already presentres.constructorAccessor= constructorAccessor;return res; }
通过上面,获取到 Constructor 了。
接下来就只需调用其相应构造器的 newInstance(),即返回实例了。
// return tmpConstructor.newInstance((Object[])null); // java.lang.reflect.Constructor @CallerSensitivepublicTnewInstance(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)thrownewIllegalArgumentException("Cannot reflectively create enum objects");ConstructorAccessor ca = constructorAccessor; // read volatileif (ca ==null) { ca =acquireConstructorAccessor(); } @SuppressWarnings("unchecked")T inst = (T) ca.newInstance(initargs);return inst; }// sun.reflect.DelegatingConstructorAccessorImplpublicObjectnewInstance(Object[] args) throws InstantiationException, IllegalArgumentException,InvocationTargetException {returndelegate.newInstance(args); }// sun.reflect.NativeConstructorAccessorImplpublicObjectnewInstance(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)newMethodAccessorGenerator().generateConstructor(c.getDeclaringClass(),c.getParameterTypes(),c.getExceptionTypes(),c.getModifiers());parent.setDelegate(acc); }// 调用native方法,进行调用 constructorreturnnewInstance0(c, args); }
// Returns an array of "root" methods. These Method objects must NOT// be propagated to the outside world, but must instead be copied// via ReflectionFactory.copyMethod.privateMethod[] privateGetDeclaredMethods(boolean publicOnly) {checkInitted();Method[] res;ReflectionData<T> rd =reflectionData();if (rd !=null) { res = publicOnly ?rd.declaredPublicMethods:rd.declaredMethods;if (res !=null) return res; }// No cached value available; request value from VM res =Reflection.filterMethods(this,getDeclaredMethods0(publicOnly));if (rd !=null) {if (publicOnly) {rd.declaredPublicMethods= res; } else {rd.declaredMethods= res; } }return res; }
privatestaticMethodsearchMethods(Method[] methods,String name,Class<?>[] parameterTypes) {Method res =null;// 使用常量池,避免重复创建StringString internedName =name.intern();for (int i =0; i <methods.length; i++) {Method m = methods[i];if (m.getName() == internedName&&arrayContentsEq(parameterTypes,m.getParameterTypes())&& (res ==null||res.getReturnType().isAssignableFrom(m.getReturnType()))) res = m; }return (res ==null? res :getReflectionFactory().copyMethod(res)); }
// probably make the implementation more scalable.privateMethodAccessoracquireMethodAccessor() {// First check to see if one has been created yet, and take it// if soMethodAccessor tmp =null;if (root !=null) tmp =root.getMethodAccessor();if (tmp !=null) {// 存在缓存时,存入 methodAccessor,否则调用 ReflectionFactory 创建新的 MethodAccessor methodAccessor = tmp; } else {// Otherwise fabricate one and propagate it up to the root tmp =reflectionFactory.newMethodAccessor(this);setMethodAccessor(tmp); }return tmp; }// sun.reflect.ReflectionFactorypublicMethodAccessornewMethodAccessor(Method method) {checkInitted();if (noInflation &&!ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {returnnewMethodAccessorGenerator().generateMethod(method.getDeclaringClass(),method.getName(),method.getParameterTypes(),method.getReturnType(),method.getExceptionTypes(),method.getModifiers()); } else {NativeMethodAccessorImpl acc =newNativeMethodAccessorImpl(method);DelegatingMethodAccessorImpl res =newDelegatingMethodAccessorImpl(acc);acc.setParent(res);return res; } }
两个Accessor详情:
// NativeMethodAccessorImpl / DelegatingMethodAccessorImplclassNativeMethodAccessorImplextendsMethodAccessorImpl {privatefinalMethod method;privateDelegatingMethodAccessorImpl parent;privateint numInvocations;NativeMethodAccessorImpl(Method method) {this.method= method; }publicObjectinvoke(Object obj,Object[] args)throwsIllegalArgumentException,InvocationTargetException {// We can't inflate methods belonging to vm-anonymous classes 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(method.getDeclaringClass())) {MethodAccessorImpl acc = (MethodAccessorImpl)newMethodAccessorGenerator().generateMethod(method.getDeclaringClass(),method.getName(),method.getParameterTypes(),method.getReturnType(),method.getExceptionTypes(),method.getModifiers());parent.setDelegate(acc); }returninvoke0(method, obj, args); }voidsetParent(DelegatingMethodAccessorImpl parent) {this.parent= parent; }privatestaticnativeObjectinvoke0(Method m,Object obj,Object[] args);}classDelegatingMethodAccessorImplextendsMethodAccessorImpl {privateMethodAccessorImpl delegate;DelegatingMethodAccessorImpl(MethodAccessorImpl delegate) {setDelegate(delegate); }publicObjectinvoke(Object obj,Object[] args)throwsIllegalArgumentException,InvocationTargetException {returndelegate.invoke(obj, args); }voidsetDelegate(MethodAccessorImpl delegate) {this.delegate= delegate; }}
publicObjectinvoke(Object obj,Object[] args) throws IllegalArgumentException,InvocationTargetException {// We can't inflate methods belonging to vm-anonymous classes 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(method.getDeclaringClass())) {MethodAccessorImpl acc = (MethodAccessorImpl)newMethodAccessorGenerator().generateMethod(method.getDeclaringClass(),method.getName(),method.getParameterTypes(),method.getReturnType(),method.getExceptionTypes(),method.getModifiers());parent.setDelegate(acc); }// invoke0 是个 native 方法,由jvm进行调用业务方法。从而完成反射调用功能。returninvoke0(method, obj, args); }
其中, generateMethod() 是生成具体类的方法:
/** This routine is not thread-safe */publicMethodAccessorgenerateMethod(Class<?> declaringClass,String name,Class<?>[] parameterTypes,Class<?> returnType,Class<?>[] checkedExceptions,int modifiers) {return (MethodAccessor) generate(declaringClass, name, parameterTypes, returnType, checkedExceptions, modifiers,false,false,null); }
generate() 戳详情。
/** This routine is not thread-safe */privateMagicAccessorImplgenerate(finalClass<?> declaringClass,String name,Class<?>[] parameterTypes,Class<?> returnType,Class<?>[] checkedExceptions,int modifiers,boolean isConstructor,boolean forSerialization,Class<?> serializationTargetClass) {ByteVector vec =ByteVectorFactory.create(); asm =newClassFileAssembler(vec);this.declaringClass= declaringClass;this.parameterTypes= parameterTypes;this.returnType= returnType;this.modifiers= modifiers;this.isConstructor= isConstructor;this.forSerialization= forSerialization;asm.emitMagicAndVersion();// Constant pool entries:// ( * = Boxing information: optional)// (+ = Shared entries provided by AccessorGenerator)// (^ = Only present if generating SerializationConstructorAccessor)// [UTF-8] [This class's name]// [CONSTANT_Class_info] for above// [UTF-8] "sun/reflect/{MethodAccessorImpl,ConstructorAccessorImpl,SerializationConstructorAccessorImpl}"// [CONSTANT_Class_info] for above// [UTF-8] [Target class's name]// [CONSTANT_Class_info] for above// ^ [UTF-8] [Serialization: Class's name in which to invoke constructor]// ^ [CONSTANT_Class_info] for above// [UTF-8] target method or constructor name// [UTF-8] target method or constructor signature// [CONSTANT_NameAndType_info] for above// [CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info] for target method// [UTF-8] "invoke" or "newInstance"// [UTF-8] invoke or newInstance descriptor// [UTF-8] descriptor for type of non-primitive parameter 1// [CONSTANT_Class_info] for type of non-primitive parameter 1// ...// [UTF-8] descriptor for type of non-primitive parameter n// [CONSTANT_Class_info] for type of non-primitive parameter n// + [UTF-8] "java/lang/Exception"// + [CONSTANT_Class_info] for above// + [UTF-8] "java/lang/ClassCastException"// + [CONSTANT_Class_info] for above// + [UTF-8] "java/lang/NullPointerException"// + [CONSTANT_Class_info] for above// + [UTF-8] "java/lang/IllegalArgumentException"// + [CONSTANT_Class_info] for above// + [UTF-8] "java/lang/InvocationTargetException"// + [CONSTANT_Class_info] for above// + [UTF-8] "<init>"// + [UTF-8] "()V"// + [CONSTANT_NameAndType_info] for above// + [CONSTANT_Methodref_info] for NullPointerException's constructor// + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor// + [UTF-8] "(Ljava/lang/String;)V"// + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/String;)V"// + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor taking a String// + [UTF-8] "(Ljava/lang/Throwable;)V"// + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/Throwable;)V"// + [CONSTANT_Methodref_info] for InvocationTargetException's constructor// + [CONSTANT_Methodref_info] for "super()"// + [UTF-8] "java/lang/Object"// + [CONSTANT_Class_info] for above// + [UTF-8] "toString"// + [UTF-8] "()Ljava/lang/String;"// + [CONSTANT_NameAndType_info] for "toString()Ljava/lang/String;"// + [CONSTANT_Methodref_info] for Object's toString method// + [UTF-8] "Code"// + [UTF-8] "Exceptions"// * [UTF-8] "java/lang/Boolean"// * [CONSTANT_Class_info] for above// * [UTF-8] "(Z)V"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "booleanValue"// * [UTF-8] "()Z"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "java/lang/Byte"// * [CONSTANT_Class_info] for above// * [UTF-8] "(B)V"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "byteValue"// * [UTF-8] "()B"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "java/lang/Character"// * [CONSTANT_Class_info] for above// * [UTF-8] "(C)V"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "charValue"// * [UTF-8] "()C"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "java/lang/Double"// * [CONSTANT_Class_info] for above// * [UTF-8] "(D)V"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "doubleValue"// * [UTF-8] "()D"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "java/lang/Float"// * [CONSTANT_Class_info] for above// * [UTF-8] "(F)V"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "floatValue"// * [UTF-8] "()F"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "java/lang/Integer"// * [CONSTANT_Class_info] for above// * [UTF-8] "(I)V"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "intValue"// * [UTF-8] "()I"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "java/lang/Long"// * [CONSTANT_Class_info] for above// * [UTF-8] "(J)V"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "longValue"// * [UTF-8] "()J"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "java/lang/Short"// * [CONSTANT_Class_info] for above// * [UTF-8] "(S)V"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for above// * [UTF-8] "shortValue"// * [UTF-8] "()S"// * [CONSTANT_NameAndType_info] for above// * [CONSTANT_Methodref_info] for aboveshort numCPEntries = NUM_BASE_CPOOL_ENTRIES + NUM_COMMON_CPOOL_ENTRIES;boolean usesPrimitives =usesPrimitiveTypes();if (usesPrimitives) { numCPEntries += NUM_BOXING_CPOOL_ENTRIES; }if (forSerialization) { numCPEntries += NUM_SERIALIZATION_CPOOL_ENTRIES; }// Add in variable-length number of entries to be able to describe// non-primitive parameter types and checked exceptions. numCPEntries += (short) (2*numNonPrimitiveParameterTypes());asm.emitShort(add(numCPEntries, S1));finalString generatedName =generateName(isConstructor, forSerialization);asm.emitConstantPoolUTF8(generatedName);asm.emitConstantPoolClass(asm.cpi()); thisClass =asm.cpi();if (isConstructor) {if (forSerialization) {asm.emitConstantPoolUTF8 ("sun/reflect/SerializationConstructorAccessorImpl"); } else {asm.emitConstantPoolUTF8("sun/reflect/ConstructorAccessorImpl"); } } else {asm.emitConstantPoolUTF8("sun/reflect/MethodAccessorImpl"); }asm.emitConstantPoolClass(asm.cpi()); superClass =asm.cpi();asm.emitConstantPoolUTF8(getClassName(declaringClass,false));asm.emitConstantPoolClass(asm.cpi()); targetClass =asm.cpi();short serializationTargetClassIdx = (short) 0;if (forSerialization) {asm.emitConstantPoolUTF8(getClassName(serializationTargetClass,false));asm.emitConstantPoolClass(asm.cpi()); serializationTargetClassIdx =asm.cpi(); }asm.emitConstantPoolUTF8(name);asm.emitConstantPoolUTF8(buildInternalSignature());asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1),asm.cpi());if (isInterface()) {asm.emitConstantPoolInterfaceMethodref(targetClass,asm.cpi()); } else {if (forSerialization) {asm.emitConstantPoolMethodref(serializationTargetClassIdx,asm.cpi()); } else {asm.emitConstantPoolMethodref(targetClass,asm.cpi()); } } targetMethodRef =asm.cpi();if (isConstructor) {asm.emitConstantPoolUTF8("newInstance"); } else {asm.emitConstantPoolUTF8("invoke"); } invokeIdx =asm.cpi();if (isConstructor) {asm.emitConstantPoolUTF8("([Ljava/lang/Object;)Ljava/lang/Object;"); } else {asm.emitConstantPoolUTF8 ("(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"); } invokeDescriptorIdx =asm.cpi();// Output class information for non-primitive parameter types nonPrimitiveParametersBaseIdx =add(asm.cpi(), S2);for (int i =0; i <parameterTypes.length; i++) {Class<?> c = parameterTypes[i];if (!isPrimitive(c)) {asm.emitConstantPoolUTF8(getClassName(c,false));asm.emitConstantPoolClass(asm.cpi()); } }// Entries common to FieldAccessor, MethodAccessor and ConstructorAccessoremitCommonConstantPoolEntries();// Boxing entriesif (usesPrimitives) {emitBoxingContantPoolEntries(); }if (asm.cpi() != numCPEntries) {thrownewInternalError("Adjust this code (cpi = "+asm.cpi() +", numCPEntries = "+ numCPEntries +")"); }// Access flagsasm.emitShort(ACC_PUBLIC);// This classasm.emitShort(thisClass);// Superclassasm.emitShort(superClass);// Interfaces count and interfacesasm.emitShort(S0);// Fields count and fieldsasm.emitShort(S0);// Methods count and methodsasm.emitShort(NUM_METHODS);emitConstructor();emitInvoke();// Additional attributes (none)asm.emitShort(S0);// Load classvec.trim();finalbyte[] bytes =vec.getData();// Note: the class loader is the only thing that really matters// here -- it's important to get the generated code into the// same namespace as the target class. Since the generated code// is privileged anyway, the protection domain probably doesn't// matter.returnAccessController.doPrivileged(newPrivilegedAction<MagicAccessorImpl>() {publicMagicAccessorImplrun() {try {return (MagicAccessorImpl)ClassDefiner.defineClass (generatedName, bytes,0,bytes.length,declaringClass.getClassLoader()).newInstance(); } catch (InstantiationException | IllegalAccessException e) {thrownewInternalError(e); } } }); }