1 /*
2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package java.lang.reflect;
27 
28 import dalvik.annotation.optimization.FastNative;
29 
30 import java.lang.annotation.Annotation;
31 import java.util.Objects;
32 import libcore.reflect.AnnotatedElements;
33 import libcore.reflect.GenericSignatureParser;
34 import libcore.reflect.ListOfTypes;
35 import libcore.reflect.Types;
36 import libcore.util.EmptyArray;
37 
38 /**
39  * A shared superclass for the common functionality of {@link Method}
40  * and {@link Constructor}.
41  *
42  * @since 1.8
43  */
44 public abstract class Executable extends AccessibleObject
45     implements Member, GenericDeclaration {
46     /*
47      * Only grant package-visibility to the constructor.
48      */
Executable()49     Executable() {}
50 
51     /**
52      * Does the Executable have generic information.
53      */
hasGenericInformation()54     abstract boolean hasGenericInformation();
55 
equalParamTypes(Class<?>[] params1, Class<?>[] params2)56     boolean equalParamTypes(Class<?>[] params1, Class<?>[] params2) {
57         /* Avoid unnecessary cloning */
58         if (params1.length == params2.length) {
59             for (int i = 0; i < params1.length; i++) {
60                 if (params1[i] != params2[i])
61                     return false;
62             }
63             return true;
64         }
65         return false;
66     }
67 
separateWithCommas(Class<?>[] types, StringBuilder sb)68     void separateWithCommas(Class<?>[] types, StringBuilder sb) {
69         for (int j = 0; j < types.length; j++) {
70             sb.append(types[j].getTypeName());
71             if (j < (types.length - 1))
72                 sb.append(",");
73         }
74 
75     }
76 
printModifiersIfNonzero(StringBuilder sb, int mask, boolean isDefault)77     void printModifiersIfNonzero(StringBuilder sb, int mask, boolean isDefault) {
78         int mod = getModifiers() & mask;
79 
80         if (mod != 0 && !isDefault) {
81             sb.append(Modifier.toString(mod)).append(' ');
82         } else {
83             int access_mod = mod & Modifier.ACCESS_MODIFIERS;
84             if (access_mod != 0)
85                 sb.append(Modifier.toString(access_mod)).append(' ');
86             if (isDefault)
87                 sb.append("default ");
88             mod = (mod & ~Modifier.ACCESS_MODIFIERS);
89             if (mod != 0)
90                 sb.append(Modifier.toString(mod)).append(' ');
91         }
92     }
93 
sharedToString(int modifierMask, boolean isDefault, Class<?>[] parameterTypes, Class<?>[] exceptionTypes)94     String sharedToString(int modifierMask,
95                           boolean isDefault,
96                           Class<?>[] parameterTypes,
97                           Class<?>[] exceptionTypes) {
98         try {
99             StringBuilder sb = new StringBuilder();
100 
101             printModifiersIfNonzero(sb, modifierMask, isDefault);
102             specificToStringHeader(sb);
103 
104             sb.append('(');
105             separateWithCommas(parameterTypes, sb);
106             sb.append(')');
107             if (exceptionTypes.length > 0) {
108                 sb.append(" throws ");
109                 separateWithCommas(exceptionTypes, sb);
110             }
111             return sb.toString();
112         } catch (Exception e) {
113             return "<" + e + ">";
114         }
115     }
116 
117     /**
118      * Generate toString header information specific to a method or
119      * constructor.
120      */
specificToStringHeader(StringBuilder sb)121     abstract void specificToStringHeader(StringBuilder sb);
122 
sharedToGenericString(int modifierMask, boolean isDefault)123     String sharedToGenericString(int modifierMask, boolean isDefault) {
124         try {
125             StringBuilder sb = new StringBuilder();
126 
127             printModifiersIfNonzero(sb, modifierMask, isDefault);
128 
129             TypeVariable<?>[] typeparms = getTypeParameters();
130             if (typeparms.length > 0) {
131                 boolean first = true;
132                 sb.append('<');
133                 for(TypeVariable<?> typeparm: typeparms) {
134                     if (!first)
135                         sb.append(',');
136                     // Class objects can't occur here; no need to test
137                     // and call Class.getName().
138                     sb.append(typeparm.toString());
139                     first = false;
140                 }
141                 sb.append("> ");
142             }
143 
144             specificToGenericStringHeader(sb);
145 
146             sb.append('(');
147             Type[] params = getGenericParameterTypes();
148             for (int j = 0; j < params.length; j++) {
149                 String param = params[j].getTypeName();
150                 if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
151                     param = param.replaceFirst("\\[\\]$", "...");
152                 sb.append(param);
153                 if (j < (params.length - 1))
154                     sb.append(',');
155             }
156             sb.append(')');
157             Type[] exceptions = getGenericExceptionTypes();
158             if (exceptions.length > 0) {
159                 sb.append(" throws ");
160                 for (int k = 0; k < exceptions.length; k++) {
161                     sb.append((exceptions[k] instanceof Class)?
162                               ((Class)exceptions[k]).getName():
163                               exceptions[k].toString());
164                     if (k < (exceptions.length - 1))
165                         sb.append(',');
166                 }
167             }
168             return sb.toString();
169         } catch (Exception e) {
170             return "<" + e + ">";
171         }
172     }
173 
174     /**
175      * Generate toGenericString header information specific to a
176      * method or constructor.
177      */
specificToGenericStringHeader(StringBuilder sb)178     abstract void specificToGenericStringHeader(StringBuilder sb);
179 
180     /**
181      * Returns the {@code Class} object representing the class or interface
182      * that declares the executable represented by this object.
183      */
getDeclaringClass()184     public abstract Class<?> getDeclaringClass();
185 
186     /**
187      * Returns the name of the executable represented by this object.
188      */
getName()189     public abstract String getName();
190 
191     /**
192      * Returns the Java language {@linkplain Modifier modifiers} for
193      * the executable represented by this object.
194      */
getModifiers()195     public abstract int getModifiers();
196 
197     /**
198      * Returns an array of {@code TypeVariable} objects that represent the
199      * type variables declared by the generic declaration represented by this
200      * {@code GenericDeclaration} object, in declaration order.  Returns an
201      * array of length 0 if the underlying generic declaration declares no type
202      * variables.
203      *
204      * @return an array of {@code TypeVariable} objects that represent
205      *     the type variables declared by this generic declaration
206      * @throws GenericSignatureFormatError if the generic
207      *     signature of this generic declaration does not conform to
208      *     the format specified in
209      *     <cite>The Java&trade; Virtual Machine Specification</cite>
210      */
getTypeParameters()211     public abstract TypeVariable<?>[] getTypeParameters();
212 
213     /**
214      * Returns an array of {@code Class} objects that represent the formal
215      * parameter types, in declaration order, of the executable
216      * represented by this object.  Returns an array of length
217      * 0 if the underlying executable takes no parameters.
218      *
219      * @return the parameter types for the executable this object
220      * represents
221      */
getParameterTypes()222     public abstract Class<?>[] getParameterTypes();
223 
224     /**
225      * Returns the number of formal parameters (whether explicitly
226      * declared or implicitly declared or neither) for the executable
227      * represented by this object.
228      *
229      * @since 1.8
230      * @return The number of formal parameters for the executable this
231      * object represents
232      */
getParameterCount()233     public int getParameterCount() {
234         throw new AbstractMethodError();
235     }
236 
237     /**
238      * Returns an array of {@code Type} objects that represent the formal
239      * parameter types, in declaration order, of the executable represented by
240      * this object. Returns an array of length 0 if the
241      * underlying executable takes no parameters.
242      *
243      * <p>If a formal parameter type is a parameterized type,
244      * the {@code Type} object returned for it must accurately reflect
245      * the actual type parameters used in the source code.
246      *
247      * <p>If a formal parameter type is a type variable or a parameterized
248      * type, it is created. Otherwise, it is resolved.
249      *
250      * @return an array of {@code Type}s that represent the formal
251      *     parameter types of the underlying executable, in declaration order
252      * @throws GenericSignatureFormatError
253      *     if the generic method signature does not conform to the format
254      *     specified in
255      *     <cite>The Java&trade; Virtual Machine Specification</cite>
256      * @throws TypeNotPresentException if any of the parameter
257      *     types of the underlying executable refers to a non-existent type
258      *     declaration
259      * @throws MalformedParameterizedTypeException if any of
260      *     the underlying executable's parameter types refer to a parameterized
261      *     type that cannot be instantiated for any reason
262      */
getGenericParameterTypes()263     public Type[] getGenericParameterTypes() {
264         // Android-changed: Changed to use Types / getMethodOrConstructorGenericInfoInternal()
265         return Types.getTypeArray(
266                 getMethodOrConstructorGenericInfoInternal().genericParameterTypes, false);
267     }
268 
269     /**
270      * Behaves like {@code getGenericParameterTypes}, but returns type
271      * information for all parameters, including synthetic parameters.
272      */
getAllGenericParameterTypes()273     Type[] getAllGenericParameterTypes() {
274         final boolean genericInfo = hasGenericInformation();
275 
276         // Easy case: we don't have generic parameter information.  In
277         // this case, we just return the result of
278         // getParameterTypes().
279         if (!genericInfo) {
280             return getParameterTypes();
281         } else {
282             final boolean realParamData = hasRealParameterData();
283             final Type[] genericParamTypes = getGenericParameterTypes();
284             final Type[] nonGenericParamTypes = getParameterTypes();
285             final Type[] out = new Type[nonGenericParamTypes.length];
286             final Parameter[] params = getParameters();
287             int fromidx = 0;
288             // If we have real parameter data, then we use the
289             // synthetic and mandate flags to our advantage.
290             if (realParamData) {
291                 for (int i = 0; i < out.length; i++) {
292                     final Parameter param = params[i];
293                     if (param.isSynthetic() || param.isImplicit()) {
294                         // If we hit a synthetic or mandated parameter,
295                         // use the non generic parameter info.
296                         out[i] = nonGenericParamTypes[i];
297                     } else {
298                         // Otherwise, use the generic parameter info.
299                         out[i] = genericParamTypes[fromidx];
300                         fromidx++;
301                     }
302                 }
303             } else {
304                 // Otherwise, use the non-generic parameter data.
305                 // Without method parameter reflection data, we have
306                 // no way to figure out which parameters are
307                 // synthetic/mandated, thus, no way to match up the
308                 // indexes.
309                 return genericParamTypes.length == nonGenericParamTypes.length ?
310                     genericParamTypes : nonGenericParamTypes;
311             }
312             return out;
313         }
314     }
315 
316     /**
317      * Returns an array of {@code Parameter} objects that represent
318      * all the parameters to the underlying executable represented by
319      * this object.  Returns an array of length 0 if the executable
320      * has no parameters.
321      *
322      * <p>The parameters of the underlying executable do not necessarily
323      * have unique names, or names that are legal identifiers in the
324      * Java programming language (JLS 3.8).
325      *
326      * @since 1.8
327      * @throws MalformedParametersException if the class file contains
328      * a MethodParameters attribute that is improperly formatted.
329      * @return an array of {@code Parameter} objects representing all
330      * the parameters to the executable this object represents.
331      */
getParameters()332     public Parameter[] getParameters() {
333         // TODO: This may eventually need to be guarded by security
334         // mechanisms similar to those in Field, Method, etc.
335         //
336         // Need to copy the cached array to prevent users from messing
337         // with it.  Since parameters are immutable, we can
338         // shallow-copy.
339         return privateGetParameters().clone();
340     }
341 
synthesizeAllParams()342     private Parameter[] synthesizeAllParams() {
343         final int realparams = getParameterCount();
344         final Parameter[] out = new Parameter[realparams];
345         for (int i = 0; i < realparams; i++)
346             // TODO: is there a way to synthetically derive the
347             // modifiers?  Probably not in the general case, since
348             // we'd have no way of knowing about them, but there
349             // may be specific cases.
350             out[i] = new Parameter("arg" + i, 0, this, i);
351         return out;
352     }
353 
verifyParameters(final Parameter[] parameters)354     private void verifyParameters(final Parameter[] parameters) {
355         final int mask = Modifier.FINAL | Modifier.SYNTHETIC | Modifier.MANDATED;
356 
357         if (getParameterTypes().length != parameters.length)
358             throw new MalformedParametersException("Wrong number of parameters in MethodParameters attribute");
359 
360         for (Parameter parameter : parameters) {
361             final String name = parameter.getRealName();
362             final int mods = parameter.getModifiers();
363 
364             if (name != null) {
365                 if (name.isEmpty() || name.indexOf('.') != -1 ||
366                     name.indexOf(';') != -1 || name.indexOf('[') != -1 ||
367                     name.indexOf('/') != -1) {
368                     throw new MalformedParametersException("Invalid parameter name \"" + name + "\"");
369                 }
370             }
371 
372             if (mods != (mods & mask)) {
373                 throw new MalformedParametersException("Invalid parameter modifiers");
374             }
375         }
376     }
377 
privateGetParameters()378     private Parameter[] privateGetParameters() {
379         // Use tmp to avoid multiple writes to a volatile.
380         Parameter[] tmp = parameters;
381 
382         if (tmp == null) {
383             // Otherwise, go to the JVM to get them
384             try {
385                 tmp = getParameters0();
386             } catch(IllegalArgumentException e) {
387                 // Rethrow ClassFormatErrors
388                 // Android-changed: Exception changed to be more descriptive.
389                 MalformedParametersException e2 =
390                         new MalformedParametersException(
391                                 "Invalid parameter metadata in class file");
392                 e2.initCause(e);
393                 throw e2;
394             }
395 
396             // If we get back nothing, then synthesize parameters
397             if (tmp == null) {
398                 hasRealParameterData = false;
399                 tmp = synthesizeAllParams();
400             } else {
401                 hasRealParameterData = true;
402                 verifyParameters(tmp);
403             }
404 
405             parameters = tmp;
406         }
407 
408         return tmp;
409     }
410 
hasRealParameterData()411     boolean hasRealParameterData() {
412         // If this somehow gets called before parameters gets
413         // initialized, force it into existence.
414         if (parameters == null) {
415             privateGetParameters();
416         }
417         return hasRealParameterData;
418     }
419 
420     private transient volatile boolean hasRealParameterData;
421     private transient volatile Parameter[] parameters;
422 
423     @FastNative
getParameters0()424     private native Parameter[] getParameters0();
425 
426     /**
427      * Returns an array of {@code Class} objects that represent the
428      * types of exceptions declared to be thrown by the underlying
429      * executable represented by this object.  Returns an array of
430      * length 0 if the executable declares no exceptions in its {@code
431      * throws} clause.
432      *
433      * @return the exception types declared as being thrown by the
434      * executable this object represents
435      */
getExceptionTypes()436     public abstract Class<?>[] getExceptionTypes();
437 
438     /**
439      * Returns an array of {@code Type} objects that represent the
440      * exceptions declared to be thrown by this executable object.
441      * Returns an array of length 0 if the underlying executable declares
442      * no exceptions in its {@code throws} clause.
443      *
444      * <p>If an exception type is a type variable or a parameterized
445      * type, it is created. Otherwise, it is resolved.
446      *
447      * @return an array of Types that represent the exception types
448      *     thrown by the underlying executable
449      * @throws GenericSignatureFormatError
450      *     if the generic method signature does not conform to the format
451      *     specified in
452      *     <cite>The Java&trade; Virtual Machine Specification</cite>
453      * @throws TypeNotPresentException if the underlying executable's
454      *     {@code throws} clause refers to a non-existent type declaration
455      * @throws MalformedParameterizedTypeException if
456      *     the underlying executable's {@code throws} clause refers to a
457      *     parameterized type that cannot be instantiated for any reason
458      */
getGenericExceptionTypes()459     public Type[] getGenericExceptionTypes() {
460         // Android-changed: Changed to use Types / getMethodOrConstructorGenericInfoInternal()
461         return Types.getTypeArray(
462                 getMethodOrConstructorGenericInfoInternal().genericExceptionTypes, false);
463     }
464 
465     /**
466      * Returns a string describing this {@code Executable}, including
467      * any type parameters.
468      * @return a string describing this {@code Executable}, including
469      * any type parameters
470      */
toGenericString()471     public abstract String toGenericString();
472 
473     /**
474      * Returns {@code true} if this executable was declared to take a
475      * variable number of arguments; returns {@code false} otherwise.
476      *
477      * @return {@code true} if an only if this executable was declared
478      * to take a variable number of arguments.
479      */
isVarArgs()480     public boolean isVarArgs()  {
481         // Android-changed: Slightly more efficient.
482         return (accessFlags & Modifier.VARARGS) != 0;
483     }
484 
485     /**
486      * Returns {@code true} if this executable is a synthetic
487      * construct; returns {@code false} otherwise.
488      *
489      * @return true if and only if this executable is a synthetic
490      * construct as defined by
491      * <cite>The Java&trade; Language Specification</cite>.
492      * @jls 13.1 The Form of a Binary
493      */
isSynthetic()494     public boolean isSynthetic() {
495         // Android-changed: Slightly more efficient.
496         return (accessFlags & Modifier.SYNTHETIC) != 0;
497     }
498 
499     /**
500      * Returns an array of arrays of {@code Annotation}s that
501      * represent the annotations on the formal parameters, in
502      * declaration order, of the {@code Executable} represented by
503      * this object.  Synthetic and mandated parameters (see
504      * explanation below), such as the outer "this" parameter to an
505      * inner class constructor will be represented in the returned
506      * array.  If the executable has no parameters (meaning no formal,
507      * no synthetic, and no mandated parameters), a zero-length array
508      * will be returned.  If the {@code Executable} has one or more
509      * parameters, a nested array of length zero is returned for each
510      * parameter with no annotations. The annotation objects contained
511      * in the returned arrays are serializable.  The caller of this
512      * method is free to modify the returned arrays; it will have no
513      * effect on the arrays returned to other callers.
514      *
515      * A compiler may add extra parameters that are implicitly
516      * declared in source ("mandated"), as well as parameters that
517      * are neither implicitly nor explicitly declared in source
518      * ("synthetic") to the parameter list for a method.  See {@link
519      * java.lang.reflect.Parameter} for more information.
520      *
521      * @see java.lang.reflect.Parameter
522      * @see java.lang.reflect.Parameter#getAnnotations
523      * @return an array of arrays that represent the annotations on
524      *    the formal and implicit parameters, in declaration order, of
525      *    the executable represented by this object
526      */
getParameterAnnotations()527     public abstract Annotation[][] getParameterAnnotations();
528 
529     /**
530      * {@inheritDoc}
531      * @throws NullPointerException  {@inheritDoc}
532      */
getAnnotation(Class<T> annotationClass)533     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
534         Objects.requireNonNull(annotationClass);
535         // Android-changed: Implemented natively.
536         return getAnnotationNative(annotationClass);
537     }
538     @FastNative
getAnnotationNative(Class<T> annotationClass)539     private native <T extends Annotation> T getAnnotationNative(Class<T> annotationClass);
540 
541     /**
542      * {@inheritDoc}
543      * @throws NullPointerException {@inheritDoc}
544      * @since 1.8
545      */
546     @Override
getAnnotationsByType(Class<T> annotationClass)547     public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
548         // Android-changed: Uses AnnotatedElements instead.
549         return AnnotatedElements.getDirectOrIndirectAnnotationsByType(this, annotationClass);
550     }
551 
552     /**
553      * {@inheritDoc}
554      */
getDeclaredAnnotations()555     public Annotation[] getDeclaredAnnotations()  {
556         // Android-changed: Implemented natively.
557         return getDeclaredAnnotationsNative();
558     }
559     @FastNative
getDeclaredAnnotationsNative()560     private native Annotation[] getDeclaredAnnotationsNative();
561 
562     // Android-changed: Additional ART-related fields and logic below that is shared between
563     // Method and Constructor.
564 
565     /** Bits encoding access (e.g. public, private) as well as other runtime specific flags */
566     @SuppressWarnings("unused") // set by runtime
567     private int accessFlags;
568 
569     /**
570      * The ArtMethod associated with this Executable, required for dispatching due to entrypoints
571      * Classloader is held live by the declaring class.
572      */
573     @SuppressWarnings("unused") // set by runtime
574     private long artMethod;
575 
576     /** Executable's declaring class */
577     @SuppressWarnings("unused") // set by runtime
578     private Class<?> declaringClass;
579 
580     /**
581      * Overriden method's declaring class (same as declaringClass unless declaringClass is a proxy
582      * class).
583      */
584     @SuppressWarnings("unused") // set by runtime
585     private Class<?> declaringClassOfOverriddenMethod;
586 
587     /** The method index of this method within its defining dex file */
588     @SuppressWarnings("unused") // set by runtime
589     private int dexMethodIndex;
590 
591     /**
592      * We insert native method stubs for abstract methods so we don't have to
593      * check the access flags at the time of the method call.  This results in
594      * "native abstract" methods, which can't exist.  If we see the "abstract"
595      * flag set, clear the "native" flag.
596      *
597      * We also move the DECLARED_SYNCHRONIZED flag into the SYNCHRONIZED
598      * position, because the callers of this function are trying to convey
599      * the "traditional" meaning of the flags to their callers.
600      */
fixMethodFlags(int flags)601     private static int fixMethodFlags(int flags) {
602         if ((flags & Modifier.ABSTRACT) != 0) {
603             flags &= ~Modifier.NATIVE;
604         }
605         flags &= ~Modifier.SYNCHRONIZED;
606         int ACC_DECLARED_SYNCHRONIZED = 0x00020000;
607         if ((flags & ACC_DECLARED_SYNCHRONIZED) != 0) {
608             flags |= Modifier.SYNCHRONIZED;
609         }
610         return flags & 0xffff;  // mask out bits not used by Java
611     }
612 
getModifiersInternal()613     final int getModifiersInternal() {
614         return fixMethodFlags(accessFlags);
615     }
616 
getDeclaringClassInternal()617     final Class<?> getDeclaringClassInternal() {
618         return declaringClass;
619     }
620 
621     /**
622      * Returns an array of {@code Class} objects associated with the parameter types of this
623      * Executable. If the Executable was declared with no parameters, {@code null} will be
624      * returned.
625      *
626      * @return the parameter types, or {@code null} if no parameters were declared.
627      */
628     @FastNative
getParameterTypesInternal()629     final native Class<?>[] getParameterTypesInternal();
630 
631     @FastNative
getParameterCountInternal()632     final native int getParameterCountInternal();
633 
634     // Android provides a more efficient implementation of this method for Executable than the one
635     // implemented in AnnotatedElement.
636     @Override
isAnnotationPresent(Class<? extends Annotation> annotationType)637     public final boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
638         Objects.requireNonNull(annotationType);
639         return isAnnotationPresentNative(annotationType);
640     }
641     @FastNative
isAnnotationPresentNative(Class<? extends Annotation> annotationType)642     private native boolean isAnnotationPresentNative(Class<? extends Annotation> annotationType);
643 
getParameterAnnotationsInternal()644     final Annotation[][] getParameterAnnotationsInternal() {
645         Annotation[][] parameterAnnotations = getParameterAnnotationsNative();
646         if (parameterAnnotations == null) {
647             parameterAnnotations = new Annotation[getParameterTypes().length][0];
648         }
649         return parameterAnnotations;
650     }
651     @FastNative
getParameterAnnotationsNative()652     private native Annotation[][] getParameterAnnotationsNative();
653 
654     /**
655      * @hide - exposed for use by {@link Class}.
656      */
getAccessFlags()657     public final int getAccessFlags() {
658         return accessFlags;
659     }
660 
661     /**
662      * @hide - exposed for use by {@code java.lang.invoke.*}.
663      */
getArtMethod()664     public final long getArtMethod() {
665         return artMethod;
666     }
667 
668     static final class GenericInfo {
669         final ListOfTypes genericExceptionTypes;
670         final ListOfTypes genericParameterTypes;
671         final Type genericReturnType;
672         final TypeVariable<?>[] formalTypeParameters;
673 
GenericInfo(ListOfTypes exceptions, ListOfTypes parameters, Type ret, TypeVariable<?>[] formal)674         GenericInfo(ListOfTypes exceptions, ListOfTypes parameters, Type ret,
675                 TypeVariable<?>[] formal) {
676             genericExceptionTypes = exceptions;
677             genericParameterTypes = parameters;
678             genericReturnType = ret;
679             formalTypeParameters = formal;
680         }
681     }
682 
hasGenericInformationInternal()683     final boolean hasGenericInformationInternal() {
684         return getSignatureAnnotation() != null;
685     }
686 
687     /**
688      * Returns generic information associated with this method/constructor member.
689      */
getMethodOrConstructorGenericInfoInternal()690     final GenericInfo getMethodOrConstructorGenericInfoInternal() {
691         String signatureAttribute = getSignatureAttribute();
692         Class<?>[] exceptionTypes = this.getExceptionTypes();
693         GenericSignatureParser parser =
694                 new GenericSignatureParser(this.getDeclaringClass().getClassLoader());
695         if (this instanceof Method) {
696             parser.parseForMethod(this, signatureAttribute, exceptionTypes);
697         } else {
698             parser.parseForConstructor(this, signatureAttribute, exceptionTypes);
699         }
700         return new GenericInfo(parser.exceptionTypes, parser.parameterTypes,
701                 parser.returnType, parser.formalTypeParameters);
702     }
703 
getSignatureAttribute()704     private String getSignatureAttribute() {
705         String[] annotation = getSignatureAnnotation();
706         if (annotation == null) {
707             return null;
708         }
709         StringBuilder result = new StringBuilder();
710         for (String s : annotation) {
711             result.append(s);
712         }
713         return result.toString();
714     }
715     @FastNative
getSignatureAnnotation()716     private native String[] getSignatureAnnotation();
717 
equalNameAndParametersInternal(Method m)718     final boolean equalNameAndParametersInternal(Method m) {
719         return getName().equals(m.getName()) && (compareMethodParametersInternal(m) == 0);
720     }
721 
722     @FastNative
compareMethodParametersInternal(Method meth)723     native int compareMethodParametersInternal(Method meth);
724 
725     @FastNative
getMethodNameInternal()726     final native String getMethodNameInternal();
727 
728     @FastNative
getMethodReturnTypeInternal()729     final native Class<?> getMethodReturnTypeInternal();
730 
731     /** A cheap implementation for {@link Method#isDefault()}. */
isDefaultMethodInternal()732     final boolean isDefaultMethodInternal() {
733         return (accessFlags & Modifier.DEFAULT) != 0;
734     }
735 
736     /** A cheap implementation for {@link Method#isBridge()}. */
isBridgeMethodInternal()737     final boolean isBridgeMethodInternal() {
738         return (accessFlags & Modifier.BRIDGE) != 0;
739     }
740 }
741