Home | History | Annotate | Download | only in reflect
      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      */
     49     Executable() {}
     50 
     51     /**
     52      * Does the Executable have generic information.
     53      */
     54     abstract boolean hasGenericInformation();
     55 
     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 
     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 
     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 
     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      */
    121     abstract void specificToStringHeader(StringBuilder sb);
    122 
    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      */
    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      */
    184     public abstract Class<?> getDeclaringClass();
    185 
    186     /**
    187      * Returns the name of the executable represented by this object.
    188      */
    189     public abstract String getName();
    190 
    191     /**
    192      * Returns the Java language {@linkplain Modifier modifiers} for
    193      * the executable represented by this object.
    194      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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 
    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 
    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 
    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 
    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
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    527     public abstract Annotation[][] getParameterAnnotations();
    528 
    529     /**
    530      * {@inheritDoc}
    531      * @throws NullPointerException  {@inheritDoc}
    532      */
    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
    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
    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      */
    555     public Annotation[] getDeclaredAnnotations()  {
    556         // Android-changed: Implemented natively.
    557         return getDeclaredAnnotationsNative();
    558     }
    559     @FastNative
    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      */
    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 
    613     final int getModifiersInternal() {
    614         return fixMethodFlags(accessFlags);
    615     }
    616 
    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
    629     final native Class<?>[] getParameterTypesInternal();
    630 
    631     @FastNative
    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
    637     public final boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
    638         Objects.requireNonNull(annotationType);
    639         return isAnnotationPresentNative(annotationType);
    640     }
    641     @FastNative
    642     private native boolean isAnnotationPresentNative(Class<? extends Annotation> annotationType);
    643 
    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
    652     private native Annotation[][] getParameterAnnotationsNative();
    653 
    654     /**
    655      * @hide - exposed for use by {@link Class}.
    656      */
    657     public final int getAccessFlags() {
    658         return accessFlags;
    659     }
    660 
    661     /**
    662      * @hide - exposed for use by {@code java.lang.invoke.*}.
    663      */
    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 
    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 
    683     final boolean hasGenericInformationInternal() {
    684         return getSignatureAnnotation() != null;
    685     }
    686 
    687     /**
    688      * Returns generic information associated with this method/constructor member.
    689      */
    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 
    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
    716     private native String[] getSignatureAnnotation();
    717 
    718     final boolean equalNameAndParametersInternal(Method m) {
    719         return getName().equals(m.getName()) && (compareMethodParametersInternal(m) == 0);
    720     }
    721 
    722     @FastNative
    723     native int compareMethodParametersInternal(Method meth);
    724 
    725     @FastNative
    726     final native String getMethodNameInternal();
    727 
    728     @FastNative
    729     final native Class<?> getMethodReturnTypeInternal();
    730 
    731     /** A cheap implementation for {@link Method#isDefault()}. */
    732     final boolean isDefaultMethodInternal() {
    733         return (accessFlags & Modifier.DEFAULT) != 0;
    734     }
    735 
    736     /** A cheap implementation for {@link Method#isBridge()}. */
    737     final boolean isBridgeMethodInternal() {
    738         return (accessFlags & Modifier.BRIDGE) != 0;
    739     }
    740 }
    741