Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/reflect/MethodAccessorGenerator.java
38829 views
/*1* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.reflect;2627import java.security.AccessController;28import java.security.PrivilegedAction;2930/** Generator for sun.reflect.MethodAccessor and31sun.reflect.ConstructorAccessor objects using bytecodes to32implement reflection. A java.lang.reflect.Method or33java.lang.reflect.Constructor object can delegate its invoke or34newInstance method to an accessor using native code or to one35generated by this class. (Methods and Constructors were merged36together in this class to ensure maximum code sharing.) */3738class MethodAccessorGenerator extends AccessorGenerator {3940private static final short NUM_BASE_CPOOL_ENTRIES = (short) 12;41// One for invoke() plus one for constructor42private static final short NUM_METHODS = (short) 2;43// Only used if forSerialization is true44private static final short NUM_SERIALIZATION_CPOOL_ENTRIES = (short) 2;4546private static volatile int methodSymnum = 0;47private static volatile int constructorSymnum = 0;48private static volatile int serializationConstructorSymnum = 0;4950private Class<?> declaringClass;51private Class<?>[] parameterTypes;52private Class<?> returnType;53private boolean isConstructor;54private boolean forSerialization;5556private short targetMethodRef;57private short invokeIdx;58private short invokeDescriptorIdx;59// Constant pool index of CONSTANT_Class_info for first60// non-primitive parameter type. Should be incremented by 2.61private short nonPrimitiveParametersBaseIdx;6263MethodAccessorGenerator() {64}6566/** This routine is not thread-safe */67public MethodAccessor generateMethod(Class<?> declaringClass,68String name,69Class<?>[] parameterTypes,70Class<?> returnType,71Class<?>[] checkedExceptions,72int modifiers)73{74return (MethodAccessor) generate(declaringClass,75name,76parameterTypes,77returnType,78checkedExceptions,79modifiers,80false,81false,82null);83}8485/** This routine is not thread-safe */86public ConstructorAccessor generateConstructor(Class<?> declaringClass,87Class<?>[] parameterTypes,88Class<?>[] checkedExceptions,89int modifiers)90{91return (ConstructorAccessor) generate(declaringClass,92"<init>",93parameterTypes,94Void.TYPE,95checkedExceptions,96modifiers,97true,98false,99null);100}101102/** This routine is not thread-safe */103public SerializationConstructorAccessorImpl104generateSerializationConstructor(Class<?> declaringClass,105Class<?>[] parameterTypes,106Class<?>[] checkedExceptions,107int modifiers,108Class<?> targetConstructorClass)109{110return (SerializationConstructorAccessorImpl)111generate(declaringClass,112"<init>",113parameterTypes,114Void.TYPE,115checkedExceptions,116modifiers,117true,118true,119targetConstructorClass);120}121122/** This routine is not thread-safe */123private MagicAccessorImpl generate(final Class<?> declaringClass,124String name,125Class<?>[] parameterTypes,126Class<?> returnType,127Class<?>[] checkedExceptions,128int modifiers,129boolean isConstructor,130boolean forSerialization,131Class<?> serializationTargetClass)132{133ByteVector vec = ByteVectorFactory.create();134asm = new ClassFileAssembler(vec);135this.declaringClass = declaringClass;136this.parameterTypes = parameterTypes;137this.returnType = returnType;138this.modifiers = modifiers;139this.isConstructor = isConstructor;140this.forSerialization = forSerialization;141142asm.emitMagicAndVersion();143144// Constant pool entries:145// ( * = Boxing information: optional)146// (+ = Shared entries provided by AccessorGenerator)147// (^ = Only present if generating SerializationConstructorAccessor)148// [UTF-8] [This class's name]149// [CONSTANT_Class_info] for above150// [UTF-8] "sun/reflect/{MethodAccessorImpl,ConstructorAccessorImpl,SerializationConstructorAccessorImpl}"151// [CONSTANT_Class_info] for above152// [UTF-8] [Target class's name]153// [CONSTANT_Class_info] for above154// ^ [UTF-8] [Serialization: Class's name in which to invoke constructor]155// ^ [CONSTANT_Class_info] for above156// [UTF-8] target method or constructor name157// [UTF-8] target method or constructor signature158// [CONSTANT_NameAndType_info] for above159// [CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info] for target method160// [UTF-8] "invoke" or "newInstance"161// [UTF-8] invoke or newInstance descriptor162// [UTF-8] descriptor for type of non-primitive parameter 1163// [CONSTANT_Class_info] for type of non-primitive parameter 1164// ...165// [UTF-8] descriptor for type of non-primitive parameter n166// [CONSTANT_Class_info] for type of non-primitive parameter n167// + [UTF-8] "java/lang/Exception"168// + [CONSTANT_Class_info] for above169// + [UTF-8] "java/lang/ClassCastException"170// + [CONSTANT_Class_info] for above171// + [UTF-8] "java/lang/NullPointerException"172// + [CONSTANT_Class_info] for above173// + [UTF-8] "java/lang/IllegalArgumentException"174// + [CONSTANT_Class_info] for above175// + [UTF-8] "java/lang/InvocationTargetException"176// + [CONSTANT_Class_info] for above177// + [UTF-8] "<init>"178// + [UTF-8] "()V"179// + [CONSTANT_NameAndType_info] for above180// + [CONSTANT_Methodref_info] for NullPointerException's constructor181// + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor182// + [UTF-8] "(Ljava/lang/String;)V"183// + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/String;)V"184// + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor taking a String185// + [UTF-8] "(Ljava/lang/Throwable;)V"186// + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/Throwable;)V"187// + [CONSTANT_Methodref_info] for InvocationTargetException's constructor188// + [CONSTANT_Methodref_info] for "super()"189// + [UTF-8] "java/lang/Object"190// + [CONSTANT_Class_info] for above191// + [UTF-8] "toString"192// + [UTF-8] "()Ljava/lang/String;"193// + [CONSTANT_NameAndType_info] for "toString()Ljava/lang/String;"194// + [CONSTANT_Methodref_info] for Object's toString method195// + [UTF-8] "Code"196// + [UTF-8] "Exceptions"197// * [UTF-8] "java/lang/Boolean"198// * [CONSTANT_Class_info] for above199// * [UTF-8] "(Z)V"200// * [CONSTANT_NameAndType_info] for above201// * [CONSTANT_Methodref_info] for above202// * [UTF-8] "booleanValue"203// * [UTF-8] "()Z"204// * [CONSTANT_NameAndType_info] for above205// * [CONSTANT_Methodref_info] for above206// * [UTF-8] "java/lang/Byte"207// * [CONSTANT_Class_info] for above208// * [UTF-8] "(B)V"209// * [CONSTANT_NameAndType_info] for above210// * [CONSTANT_Methodref_info] for above211// * [UTF-8] "byteValue"212// * [UTF-8] "()B"213// * [CONSTANT_NameAndType_info] for above214// * [CONSTANT_Methodref_info] for above215// * [UTF-8] "java/lang/Character"216// * [CONSTANT_Class_info] for above217// * [UTF-8] "(C)V"218// * [CONSTANT_NameAndType_info] for above219// * [CONSTANT_Methodref_info] for above220// * [UTF-8] "charValue"221// * [UTF-8] "()C"222// * [CONSTANT_NameAndType_info] for above223// * [CONSTANT_Methodref_info] for above224// * [UTF-8] "java/lang/Double"225// * [CONSTANT_Class_info] for above226// * [UTF-8] "(D)V"227// * [CONSTANT_NameAndType_info] for above228// * [CONSTANT_Methodref_info] for above229// * [UTF-8] "doubleValue"230// * [UTF-8] "()D"231// * [CONSTANT_NameAndType_info] for above232// * [CONSTANT_Methodref_info] for above233// * [UTF-8] "java/lang/Float"234// * [CONSTANT_Class_info] for above235// * [UTF-8] "(F)V"236// * [CONSTANT_NameAndType_info] for above237// * [CONSTANT_Methodref_info] for above238// * [UTF-8] "floatValue"239// * [UTF-8] "()F"240// * [CONSTANT_NameAndType_info] for above241// * [CONSTANT_Methodref_info] for above242// * [UTF-8] "java/lang/Integer"243// * [CONSTANT_Class_info] for above244// * [UTF-8] "(I)V"245// * [CONSTANT_NameAndType_info] for above246// * [CONSTANT_Methodref_info] for above247// * [UTF-8] "intValue"248// * [UTF-8] "()I"249// * [CONSTANT_NameAndType_info] for above250// * [CONSTANT_Methodref_info] for above251// * [UTF-8] "java/lang/Long"252// * [CONSTANT_Class_info] for above253// * [UTF-8] "(J)V"254// * [CONSTANT_NameAndType_info] for above255// * [CONSTANT_Methodref_info] for above256// * [UTF-8] "longValue"257// * [UTF-8] "()J"258// * [CONSTANT_NameAndType_info] for above259// * [CONSTANT_Methodref_info] for above260// * [UTF-8] "java/lang/Short"261// * [CONSTANT_Class_info] for above262// * [UTF-8] "(S)V"263// * [CONSTANT_NameAndType_info] for above264// * [CONSTANT_Methodref_info] for above265// * [UTF-8] "shortValue"266// * [UTF-8] "()S"267// * [CONSTANT_NameAndType_info] for above268// * [CONSTANT_Methodref_info] for above269270short numCPEntries = NUM_BASE_CPOOL_ENTRIES + NUM_COMMON_CPOOL_ENTRIES;271boolean usesPrimitives = usesPrimitiveTypes();272if (usesPrimitives) {273numCPEntries += NUM_BOXING_CPOOL_ENTRIES;274}275if (forSerialization) {276numCPEntries += NUM_SERIALIZATION_CPOOL_ENTRIES;277}278279// Add in variable-length number of entries to be able to describe280// non-primitive parameter types and checked exceptions.281numCPEntries += (short) (2 * numNonPrimitiveParameterTypes());282283asm.emitShort(add(numCPEntries, S1));284285final String generatedName = generateName(isConstructor, forSerialization);286asm.emitConstantPoolUTF8(generatedName);287asm.emitConstantPoolClass(asm.cpi());288thisClass = asm.cpi();289if (isConstructor) {290if (forSerialization) {291asm.emitConstantPoolUTF8292("sun/reflect/SerializationConstructorAccessorImpl");293} else {294asm.emitConstantPoolUTF8("sun/reflect/ConstructorAccessorImpl");295}296} else {297asm.emitConstantPoolUTF8("sun/reflect/MethodAccessorImpl");298}299asm.emitConstantPoolClass(asm.cpi());300superClass = asm.cpi();301asm.emitConstantPoolUTF8(getClassName(declaringClass, false));302asm.emitConstantPoolClass(asm.cpi());303targetClass = asm.cpi();304short serializationTargetClassIdx = (short) 0;305if (forSerialization) {306asm.emitConstantPoolUTF8(getClassName(serializationTargetClass, false));307asm.emitConstantPoolClass(asm.cpi());308serializationTargetClassIdx = asm.cpi();309}310asm.emitConstantPoolUTF8(name);311asm.emitConstantPoolUTF8(buildInternalSignature());312asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());313if (isInterface()) {314asm.emitConstantPoolInterfaceMethodref(targetClass, asm.cpi());315} else {316if (forSerialization) {317asm.emitConstantPoolMethodref(serializationTargetClassIdx, asm.cpi());318} else {319asm.emitConstantPoolMethodref(targetClass, asm.cpi());320}321}322targetMethodRef = asm.cpi();323if (isConstructor) {324asm.emitConstantPoolUTF8("newInstance");325} else {326asm.emitConstantPoolUTF8("invoke");327}328invokeIdx = asm.cpi();329if (isConstructor) {330asm.emitConstantPoolUTF8("([Ljava/lang/Object;)Ljava/lang/Object;");331} else {332asm.emitConstantPoolUTF8333("(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");334}335invokeDescriptorIdx = asm.cpi();336337// Output class information for non-primitive parameter types338nonPrimitiveParametersBaseIdx = add(asm.cpi(), S2);339for (int i = 0; i < parameterTypes.length; i++) {340Class<?> c = parameterTypes[i];341if (!isPrimitive(c)) {342asm.emitConstantPoolUTF8(getClassName(c, false));343asm.emitConstantPoolClass(asm.cpi());344}345}346347// Entries common to FieldAccessor, MethodAccessor and ConstructorAccessor348emitCommonConstantPoolEntries();349350// Boxing entries351if (usesPrimitives) {352emitBoxingContantPoolEntries();353}354355if (asm.cpi() != numCPEntries) {356throw new InternalError("Adjust this code (cpi = " + asm.cpi() +357", numCPEntries = " + numCPEntries + ")");358}359360// Access flags361asm.emitShort(ACC_PUBLIC);362363// This class364asm.emitShort(thisClass);365366// Superclass367asm.emitShort(superClass);368369// Interfaces count and interfaces370asm.emitShort(S0);371372// Fields count and fields373asm.emitShort(S0);374375// Methods count and methods376asm.emitShort(NUM_METHODS);377378emitConstructor();379emitInvoke();380381// Additional attributes (none)382asm.emitShort(S0);383384// Load class385vec.trim();386final byte[] bytes = vec.getData();387// Note: the class loader is the only thing that really matters388// here -- it's important to get the generated code into the389// same namespace as the target class. Since the generated code390// is privileged anyway, the protection domain probably doesn't391// matter.392return AccessController.doPrivileged(393new PrivilegedAction<MagicAccessorImpl>() {394public MagicAccessorImpl run() {395try {396return (MagicAccessorImpl)397ClassDefiner.defineClass398(generatedName,399bytes,4000,401bytes.length,402declaringClass.getClassLoader()).newInstance();403} catch (InstantiationException | IllegalAccessException e) {404throw new InternalError(e);405}406}407});408}409410/** This emits the code for either invoke() or newInstance() */411private void emitInvoke() {412// NOTE that this code will only handle 65535 parameters since we413// use the sipush instruction to get the array index on the414// operand stack.415if (parameterTypes.length > 65535) {416throw new InternalError("Can't handle more than 65535 parameters");417}418419// Generate code into fresh code buffer420ClassFileAssembler cb = new ClassFileAssembler();421if (isConstructor) {422// 1 incoming argument423cb.setMaxLocals(2);424} else {425// 2 incoming arguments426cb.setMaxLocals(3);427}428429short illegalArgStartPC = 0;430431if (isConstructor) {432// Instantiate target class before continuing433// new <target class type>434// dup435cb.opc_new(targetClass);436cb.opc_dup();437} else {438// Setup before iterating down argument list439if (isPrimitive(returnType)) {440// new <boxing type for primitive type>441// dup442// ... (see below:)443// invokespecial <constructor for boxing type for primitive type>444// areturn445cb.opc_new(indexForPrimitiveType(returnType));446cb.opc_dup();447}448449// Get target object on operand stack if necessary.450451// We need to do an explicit null check here; we won't see452// NullPointerExceptions from the invoke bytecode, since it's453// covered by an exception handler.454if (!isStatic()) {455// aload_1456// ifnonnull <checkcast label>457// new <NullPointerException>458// dup459// invokespecial <NullPointerException ctor>460// athrow461// <checkcast label:>462// aload_1463// checkcast <target class's type>464cb.opc_aload_1();465Label l = new Label();466cb.opc_ifnonnull(l);467cb.opc_new(nullPointerClass);468cb.opc_dup();469cb.opc_invokespecial(nullPointerCtorIdx, 0, 0);470cb.opc_athrow();471l.bind();472illegalArgStartPC = cb.getLength();473cb.opc_aload_1();474cb.opc_checkcast(targetClass);475}476}477478// Have to check length of incoming array and throw479// IllegalArgumentException if not correct. A concession to the480// JCK (isn't clearly specified in the spec): we allow null in the481// case where the argument list is zero length.482// if no-arg:483// aload_2 | aload_1 (Method | Constructor)484// ifnull <success label>485// aload_2 | aload_1486// arraylength487// sipush <num parameter types>488// if_icmpeq <success label>489// new <IllegalArgumentException>490// dup491// invokespecial <IllegalArgumentException ctor>492// athrow493// <success label:>494Label successLabel = new Label();495if (parameterTypes.length == 0) {496if (isConstructor) {497cb.opc_aload_1();498} else {499cb.opc_aload_2();500}501cb.opc_ifnull(successLabel);502}503if (isConstructor) {504cb.opc_aload_1();505} else {506cb.opc_aload_2();507}508cb.opc_arraylength();509cb.opc_sipush((short) parameterTypes.length);510cb.opc_if_icmpeq(successLabel);511cb.opc_new(illegalArgumentClass);512cb.opc_dup();513cb.opc_invokespecial(illegalArgumentCtorIdx, 0, 0);514cb.opc_athrow();515successLabel.bind();516517// Iterate through incoming actual parameters, ensuring that each518// is compatible with the formal parameter type, and pushing the519// actual on the operand stack (unboxing and widening if necessary).520521short paramTypeCPIdx = nonPrimitiveParametersBaseIdx;522Label nextParamLabel = null;523byte count = 1; // both invokeinterface opcode's "count" as well as524// num args of other invoke bytecodes525for (int i = 0; i < parameterTypes.length; i++) {526Class<?> paramType = parameterTypes[i];527count += (byte) typeSizeInStackSlots(paramType);528if (nextParamLabel != null) {529nextParamLabel.bind();530nextParamLabel = null;531}532// aload_2 | aload_1533// sipush <index>534// aaload535if (isConstructor) {536cb.opc_aload_1();537} else {538cb.opc_aload_2();539}540cb.opc_sipush((short) i);541cb.opc_aaload();542if (isPrimitive(paramType)) {543// Unboxing code.544// Put parameter into temporary local variable545// astore_3 | astore_2546if (isConstructor) {547cb.opc_astore_2();548} else {549cb.opc_astore_3();550}551552// repeat for all possible widening conversions:553// aload_3 | aload_2554// instanceof <primitive boxing type>555// ifeq <next unboxing label>556// aload_3 | aload_2557// checkcast <primitive boxing type> // Note: this is "redundant",558// // but necessary for the verifier559// invokevirtual <unboxing method>560// <widening conversion bytecode, if necessary>561// goto <next parameter label>562// <next unboxing label:> ...563// last unboxing label:564// new <IllegalArgumentException>565// dup566// invokespecial <IllegalArgumentException ctor>567// athrow568569Label l = null; // unboxing label570nextParamLabel = new Label();571572for (int j = 0; j < primitiveTypes.length; j++) {573Class<?> c = primitiveTypes[j];574if (canWidenTo(c, paramType)) {575if (l != null) {576l.bind();577}578// Emit checking and unboxing code for this type579if (isConstructor) {580cb.opc_aload_2();581} else {582cb.opc_aload_3();583}584cb.opc_instanceof(indexForPrimitiveType(c));585l = new Label();586cb.opc_ifeq(l);587if (isConstructor) {588cb.opc_aload_2();589} else {590cb.opc_aload_3();591}592cb.opc_checkcast(indexForPrimitiveType(c));593cb.opc_invokevirtual(unboxingMethodForPrimitiveType(c),5940,595typeSizeInStackSlots(c));596emitWideningBytecodeForPrimitiveConversion(cb,597c,598paramType);599cb.opc_goto(nextParamLabel);600}601}602603if (l == null) {604throw new InternalError605("Must have found at least identity conversion");606}607608// Fell through; given object is null or invalid. According to609// the spec, we can throw IllegalArgumentException for both of610// these cases.611612l.bind();613cb.opc_new(illegalArgumentClass);614cb.opc_dup();615cb.opc_invokespecial(illegalArgumentCtorIdx, 0, 0);616cb.opc_athrow();617} else {618// Emit appropriate checkcast619cb.opc_checkcast(paramTypeCPIdx);620paramTypeCPIdx = add(paramTypeCPIdx, S2);621// Fall through to next argument622}623}624// Bind last goto if present625if (nextParamLabel != null) {626nextParamLabel.bind();627}628629short invokeStartPC = cb.getLength();630631// OK, ready to perform the invocation.632if (isConstructor) {633cb.opc_invokespecial(targetMethodRef, count, 0);634} else {635if (isStatic()) {636cb.opc_invokestatic(targetMethodRef,637count,638typeSizeInStackSlots(returnType));639} else {640if (isInterface()) {641if (isPrivate()) {642cb.opc_invokespecial(targetMethodRef, count, 0);643} else {644cb.opc_invokeinterface(targetMethodRef,645count,646count,647typeSizeInStackSlots(returnType));648}649} else {650cb.opc_invokevirtual(targetMethodRef,651count,652typeSizeInStackSlots(returnType));653}654}655}656657short invokeEndPC = cb.getLength();658659if (!isConstructor) {660// Box return value if necessary661if (isPrimitive(returnType)) {662cb.opc_invokespecial(ctorIndexForPrimitiveType(returnType),663typeSizeInStackSlots(returnType),6640);665} else if (returnType == Void.TYPE) {666cb.opc_aconst_null();667}668}669cb.opc_areturn();670671// We generate two exception handlers; one which is responsible672// for catching ClassCastException and NullPointerException and673// throwing IllegalArgumentException, and the other which catches674// all java/lang/Throwable objects thrown from the target method675// and wraps them in InvocationTargetExceptions.676677short classCastHandler = cb.getLength();678679// ClassCast, etc. exception handler680cb.setStack(1);681cb.opc_invokespecial(toStringIdx, 0, 1);682cb.opc_new(illegalArgumentClass);683cb.opc_dup_x1();684cb.opc_swap();685cb.opc_invokespecial(illegalArgumentStringCtorIdx, 1, 0);686cb.opc_athrow();687688short invocationTargetHandler = cb.getLength();689690// InvocationTargetException exception handler691cb.setStack(1);692cb.opc_new(invocationTargetClass);693cb.opc_dup_x1();694cb.opc_swap();695cb.opc_invokespecial(invocationTargetCtorIdx, 1, 0);696cb.opc_athrow();697698// Generate exception table. We cover the entire code sequence699// with an exception handler which catches ClassCastException and700// converts it into an IllegalArgumentException.701702ClassFileAssembler exc = new ClassFileAssembler();703704exc.emitShort(illegalArgStartPC); // start PC705exc.emitShort(invokeStartPC); // end PC706exc.emitShort(classCastHandler); // handler PC707exc.emitShort(classCastClass); // catch type708709exc.emitShort(illegalArgStartPC); // start PC710exc.emitShort(invokeStartPC); // end PC711exc.emitShort(classCastHandler); // handler PC712exc.emitShort(nullPointerClass); // catch type713714exc.emitShort(invokeStartPC); // start PC715exc.emitShort(invokeEndPC); // end PC716exc.emitShort(invocationTargetHandler); // handler PC717exc.emitShort(throwableClass); // catch type718719emitMethod(invokeIdx, cb.getMaxLocals(), cb, exc,720new short[] { invocationTargetClass });721}722723private boolean usesPrimitiveTypes() {724// We need to emit boxing/unboxing constant pool information if725// the method takes a primitive type for any of its parameters or726// returns a primitive value (except void)727if (returnType.isPrimitive()) {728return true;729}730for (int i = 0; i < parameterTypes.length; i++) {731if (parameterTypes[i].isPrimitive()) {732return true;733}734}735return false;736}737738private int numNonPrimitiveParameterTypes() {739int num = 0;740for (int i = 0; i < parameterTypes.length; i++) {741if (!parameterTypes[i].isPrimitive()) {742++num;743}744}745return num;746}747748private boolean isInterface() {749return declaringClass.isInterface();750}751752private String buildInternalSignature() {753StringBuffer buf = new StringBuffer();754buf.append("(");755for (int i = 0; i < parameterTypes.length; i++) {756buf.append(getClassName(parameterTypes[i], true));757}758buf.append(")");759buf.append(getClassName(returnType, true));760return buf.toString();761}762763private static synchronized String generateName(boolean isConstructor,764boolean forSerialization)765{766if (isConstructor) {767if (forSerialization) {768int num = ++serializationConstructorSymnum;769return "sun/reflect/GeneratedSerializationConstructorAccessor" + num;770} else {771int num = ++constructorSymnum;772return "sun/reflect/GeneratedConstructorAccessor" + num;773}774} else {775int num = ++methodSymnum;776return "sun/reflect/GeneratedMethodAccessor" + num;777}778}779}780781782