Home | History | Annotate | Download | only in reflect
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
      4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      5  *
      6  * This code is free software; you can redistribute it and/or modify it
      7  * under the terms of the GNU General Public License version 2 only, as
      8  * published by the Free Software Foundation.  Oracle designates this
      9  * particular file as subject to the "Classpath" exception as provided
     10  * by Oracle in the LICENSE file that accompanied this code.
     11  *
     12  * This code is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  * version 2 for more details (a copy is included in the LICENSE file that
     16  * accompanied this code).
     17  *
     18  * You should have received a copy of the GNU General Public License version
     19  * 2 along with this work; if not, write to the Free Software Foundation,
     20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     21  *
     22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     23  * or visit www.oracle.com if you need additional information or have any
     24  * questions.
     25  */
     26 
     27 package java.lang.reflect;
     28 
     29 import dalvik.annotation.optimization.FastNative;
     30 import java.lang.annotation.Annotation;
     31 import java.util.Comparator;
     32 import libcore.reflect.Types;
     33 import libcore.util.EmptyArray;
     34 
     35 /**
     36  * A {@code Method} provides information about, and access to, a single method
     37  * on a class or interface.  The reflected method may be a class method
     38  * or an instance method (including an abstract method).
     39  *
     40  * <p>A {@code Method} permits widening conversions to occur when matching the
     41  * actual parameters to invoke with the underlying method's formal
     42  * parameters, but it throws an {@code IllegalArgumentException} if a
     43  * narrowing conversion would occur.
     44  *
     45  * @see Member
     46  * @see java.lang.Class
     47  * @see java.lang.Class#getMethods()
     48  * @see java.lang.Class#getMethod(String, Class[])
     49  * @see java.lang.Class#getDeclaredMethods()
     50  * @see java.lang.Class#getDeclaredMethod(String, Class[])
     51  *
     52  * @author Kenneth Russell
     53  * @author Nakul Saraiya
     54  */
     55 public final class Method extends Executable  {
     56     /**
     57      * Orders methods by their name, parameters and return type.
     58      *
     59      * @hide
     60      */
     61     public static final Comparator<Method> ORDER_BY_SIGNATURE = new Comparator<Method>() {
     62         @Override public int compare(Method a, Method b) {
     63             if (a == b) {
     64                 return 0;
     65             }
     66             int comparison = a.getName().compareTo(b.getName());
     67             if (comparison == 0) {
     68                 comparison = a.compareMethodParametersInternal(b);
     69                 if (comparison == 0) {
     70                     // This is necessary for methods that have covariant return types.
     71                     Class<?> aReturnType = a.getReturnType();
     72                     Class<?> bReturnType = b.getReturnType();
     73                     if (aReturnType == bReturnType) {
     74                         comparison = 0;
     75                     } else {
     76                         comparison = aReturnType.getName().compareTo(bReturnType.getName());
     77                     }
     78                 }
     79             }
     80             return comparison;
     81         }
     82     };
     83 
     84     private Method() {
     85     }
     86 
     87     @Override
     88     boolean hasGenericInformation() {
     89         // Android-changed: Signature retrieval is handled in Executable.
     90         return super.hasGenericInformationInternal();
     91     }
     92 
     93     /**
     94      * {@inheritDoc}
     95      */
     96     @Override
     97     public Class<?> getDeclaringClass() {
     98         // Android-changed: This is handled by Executable.
     99         return super.getDeclaringClassInternal();
    100     }
    101 
    102     /**
    103      * Returns the name of the method represented by this {@code Method}
    104      * object, as a {@code String}.
    105      */
    106     @Override
    107     public String getName() {
    108         // Android-changed: This is handled by Executable.
    109         return getMethodNameInternal();
    110     }
    111 
    112     /**
    113      * {@inheritDoc}
    114      */
    115     @Override
    116     public int getModifiers() {
    117         // Android-changed: This is handled by Executable.
    118         return super.getModifiersInternal();
    119     }
    120 
    121     /**
    122      * {@inheritDoc}
    123      * @throws GenericSignatureFormatError {@inheritDoc}
    124      * @since 1.5
    125      */
    126     @Override
    127     @SuppressWarnings({"rawtypes", "unchecked"})
    128     public TypeVariable<Method>[] getTypeParameters() {
    129         // Android-changed: This is mostly handled by Executable.
    130         GenericInfo info = getMethodOrConstructorGenericInfoInternal();
    131         return (TypeVariable<Method>[]) info.formalTypeParameters.clone();
    132     }
    133 
    134     /**
    135      * Returns a {@code Class} object that represents the formal return type
    136      * of the method represented by this {@code Method} object.
    137      *
    138      * @return the return type for the method this object represents
    139      */
    140     public Class<?> getReturnType() {
    141         return getMethodReturnTypeInternal();
    142     }
    143 
    144     /**
    145      * Returns a {@code Type} object that represents the formal return
    146      * type of the method represented by this {@code Method} object.
    147      *
    148      * <p>If the return type is a parameterized type,
    149      * the {@code Type} object returned must accurately reflect
    150      * the actual type parameters used in the source code.
    151      *
    152      * <p>If the return type is a type variable or a parameterized type, it
    153      * is created. Otherwise, it is resolved.
    154      *
    155      * @return  a {@code Type} object that represents the formal return
    156      *     type of the underlying  method
    157      * @throws GenericSignatureFormatError
    158      *     if the generic method signature does not conform to the format
    159      *     specified in
    160      *     <cite>The Java&trade; Virtual Machine Specification</cite>
    161      * @throws TypeNotPresentException if the underlying method's
    162      *     return type refers to a non-existent type declaration
    163      * @throws MalformedParameterizedTypeException if the
    164      *     underlying method's return typed refers to a parameterized
    165      *     type that cannot be instantiated for any reason
    166      * @since 1.5
    167      */
    168     public Type getGenericReturnType() {
    169         // Android-changed: Modified implementation to use Executable.
    170       return Types.getType(getMethodOrConstructorGenericInfoInternal().genericReturnType);
    171     }
    172 
    173     /**
    174      * {@inheritDoc}
    175      */
    176     @Override
    177     public Class<?>[] getParameterTypes() {
    178         // Android-changed: This is handled by Executable.
    179         Class<?>[] paramTypes = super.getParameterTypesInternal();
    180         if (paramTypes == null) {
    181             return EmptyArray.CLASS;
    182         }
    183 
    184         return paramTypes;
    185     }
    186 
    187     /**
    188      * {@inheritDoc}
    189      * @since 1.8
    190      */
    191     public int getParameterCount() {
    192         // Android-changed: This is handled by Executable.
    193         return super.getParameterCountInternal();
    194     }
    195 
    196     /**
    197      * {@inheritDoc}
    198      * @throws GenericSignatureFormatError {@inheritDoc}
    199      * @throws TypeNotPresentException {@inheritDoc}
    200      * @throws MalformedParameterizedTypeException {@inheritDoc}
    201      * @since 1.5
    202      */
    203     @Override
    204     public Type[] getGenericParameterTypes() {
    205         return super.getGenericParameterTypes();
    206     }
    207 
    208     /**
    209      * {@inheritDoc}
    210      */
    211     @Override
    212     @FastNative
    213     public native Class<?>[] getExceptionTypes();
    214 
    215     /**
    216      * {@inheritDoc}
    217      * @throws GenericSignatureFormatError {@inheritDoc}
    218      * @throws TypeNotPresentException {@inheritDoc}
    219      * @throws MalformedParameterizedTypeException {@inheritDoc}
    220      * @since 1.5
    221      */
    222     @Override
    223     public Type[] getGenericExceptionTypes() {
    224         return super.getGenericExceptionTypes();
    225     }
    226 
    227     /**
    228      * Compares this {@code Method} against the specified object.  Returns
    229      * true if the objects are the same.  Two {@code Methods} are the same if
    230      * they were declared by the same class and have the same name
    231      * and formal parameter types and return type.
    232      */
    233     public boolean equals(Object obj) {
    234         if (obj != null && obj instanceof Method) {
    235             Method other = (Method)obj;
    236             if ((getDeclaringClass() == other.getDeclaringClass())
    237                 && (getName() == other.getName())) {
    238                 if (!getReturnType().equals(other.getReturnType()))
    239                     return false;
    240                 // Android-changed: Use getParameterTypes.
    241                 return equalParamTypes(getParameterTypes(), other.getParameterTypes());
    242             }
    243         }
    244         return false;
    245     }
    246 
    247     /**
    248      * Returns a hashcode for this {@code Method}.  The hashcode is computed
    249      * as the exclusive-or of the hashcodes for the underlying
    250      * method's declaring class name and the method's name.
    251      */
    252     public int hashCode() {
    253         return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
    254     }
    255 
    256     /**
    257      * Returns a string describing this {@code Method}.  The string is
    258      * formatted as the method access modifiers, if any, followed by
    259      * the method return type, followed by a space, followed by the
    260      * class declaring the method, followed by a period, followed by
    261      * the method name, followed by a parenthesized, comma-separated
    262      * list of the method's formal parameter types. If the method
    263      * throws checked exceptions, the parameter list is followed by a
    264      * space, followed by the word throws followed by a
    265      * comma-separated list of the thrown exception types.
    266      * For example:
    267      * <pre>
    268      *    public boolean java.lang.Object.equals(java.lang.Object)
    269      * </pre>
    270      *
    271      * <p>The access modifiers are placed in canonical order as
    272      * specified by "The Java Language Specification".  This is
    273      * {@code public}, {@code protected} or {@code private} first,
    274      * and then other modifiers in the following order:
    275      * {@code abstract}, {@code default}, {@code static}, {@code final},
    276      * {@code synchronized}, {@code native}, {@code strictfp}.
    277      *
    278      * @return a string describing this {@code Method}
    279      *
    280      * @jls 8.4.3 Method Modifiers
    281      */
    282     public String toString() {
    283         // Android-changed: Use getParameterTypes.
    284         return sharedToString(Modifier.methodModifiers(),
    285                               isDefault(),
    286                               getParameterTypes(),
    287                               getExceptionTypes());
    288     }
    289 
    290     @Override
    291     void specificToStringHeader(StringBuilder sb) {
    292         sb.append(getReturnType().getTypeName()).append(' ');
    293         sb.append(getDeclaringClass().getTypeName()).append('.');
    294         sb.append(getName());
    295     }
    296 
    297     /**
    298      * Returns a string describing this {@code Method}, including
    299      * type parameters.  The string is formatted as the method access
    300      * modifiers, if any, followed by an angle-bracketed
    301      * comma-separated list of the method's type parameters, if any,
    302      * followed by the method's generic return type, followed by a
    303      * space, followed by the class declaring the method, followed by
    304      * a period, followed by the method name, followed by a
    305      * parenthesized, comma-separated list of the method's generic
    306      * formal parameter types.
    307      *
    308      * If this method was declared to take a variable number of
    309      * arguments, instead of denoting the last parameter as
    310      * "<tt><i>Type</i>[]</tt>", it is denoted as
    311      * "<tt><i>Type</i>...</tt>".
    312      *
    313      * A space is used to separate access modifiers from one another
    314      * and from the type parameters or return type.  If there are no
    315      * type parameters, the type parameter list is elided; if the type
    316      * parameter list is present, a space separates the list from the
    317      * class name.  If the method is declared to throw exceptions, the
    318      * parameter list is followed by a space, followed by the word
    319      * throws followed by a comma-separated list of the generic thrown
    320      * exception types.
    321      *
    322      * <p>The access modifiers are placed in canonical order as
    323      * specified by "The Java Language Specification".  This is
    324      * {@code public}, {@code protected} or {@code private} first,
    325      * and then other modifiers in the following order:
    326      * {@code abstract}, {@code default}, {@code static}, {@code final},
    327      * {@code synchronized}, {@code native}, {@code strictfp}.
    328      *
    329      * @return a string describing this {@code Method},
    330      * include type parameters
    331      *
    332      * @since 1.5
    333      *
    334      * @jls 8.4.3 Method Modifiers
    335      */
    336     @Override
    337     public String toGenericString() {
    338         return sharedToGenericString(Modifier.methodModifiers(), isDefault());
    339     }
    340 
    341     @Override
    342     void specificToGenericStringHeader(StringBuilder sb) {
    343         Type genRetType = getGenericReturnType();
    344         sb.append(genRetType.getTypeName()).append(' ');
    345         sb.append(getDeclaringClass().getTypeName()).append('.');
    346         sb.append(getName());
    347     }
    348 
    349     /**
    350      * Invokes the underlying method represented by this {@code Method}
    351      * object, on the specified object with the specified parameters.
    352      * Individual parameters are automatically unwrapped to match
    353      * primitive formal parameters, and both primitive and reference
    354      * parameters are subject to method invocation conversions as
    355      * necessary.
    356      *
    357      * <p>If the underlying method is static, then the specified {@code obj}
    358      * argument is ignored. It may be null.
    359      *
    360      * <p>If the number of formal parameters required by the underlying method is
    361      * 0, the supplied {@code args} array may be of length 0 or null.
    362      *
    363      * <p>If the underlying method is an instance method, it is invoked
    364      * using dynamic method lookup as documented in The Java Language
    365      * Specification, Second Edition, section 15.12.4.4; in particular,
    366      * overriding based on the runtime type of the target object will occur.
    367      *
    368      * <p>If the underlying method is static, the class that declared
    369      * the method is initialized if it has not already been initialized.
    370      *
    371      * <p>If the method completes normally, the value it returns is
    372      * returned to the caller of invoke; if the value has a primitive
    373      * type, it is first appropriately wrapped in an object. However,
    374      * if the value has the type of an array of a primitive type, the
    375      * elements of the array are <i>not</i> wrapped in objects; in
    376      * other words, an array of primitive type is returned.  If the
    377      * underlying method return type is void, the invocation returns
    378      * null.
    379      *
    380      * @param obj  the object the underlying method is invoked from
    381      * @param args the arguments used for the method call
    382      * @return the result of dispatching the method represented by
    383      * this object on {@code obj} with parameters
    384      * {@code args}
    385      *
    386      * @exception IllegalAccessException    if this {@code Method} object
    387      *              is enforcing Java language access control and the underlying
    388      *              method is inaccessible.
    389      * @exception IllegalArgumentException  if the method is an
    390      *              instance method and the specified object argument
    391      *              is not an instance of the class or interface
    392      *              declaring the underlying method (or of a subclass
    393      *              or implementor thereof); if the number of actual
    394      *              and formal parameters differ; if an unwrapping
    395      *              conversion for primitive arguments fails; or if,
    396      *              after possible unwrapping, a parameter value
    397      *              cannot be converted to the corresponding formal
    398      *              parameter type by a method invocation conversion.
    399      * @exception InvocationTargetException if the underlying method
    400      *              throws an exception.
    401      * @exception NullPointerException      if the specified object is null
    402      *              and the method is an instance method.
    403      * @exception ExceptionInInitializerError if the initialization
    404      * provoked by this method fails.
    405      */
    406     @FastNative
    407     public native Object invoke(Object obj, Object... args)
    408             throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
    409 
    410     /**
    411      * Returns {@code true} if this method is a bridge
    412      * method; returns {@code false} otherwise.
    413      *
    414      * @return true if and only if this method is a bridge
    415      * method as defined by the Java Language Specification.
    416      * @since 1.5
    417      */
    418     public boolean isBridge() {
    419         // Android-changed: This is handled by Executable.
    420         return super.isBridgeMethodInternal();
    421     }
    422 
    423     /**
    424      * {@inheritDoc}
    425      * @since 1.5
    426      */
    427     @Override
    428     public boolean isVarArgs() {
    429         return super.isVarArgs();
    430     }
    431 
    432     /**
    433      * {@inheritDoc}
    434      * @jls 13.1 The Form of a Binary
    435      * @since 1.5
    436      */
    437     @Override
    438     public boolean isSynthetic() {
    439         return super.isSynthetic();
    440     }
    441 
    442     /**
    443      * Returns {@code true} if this method is a default
    444      * method; returns {@code false} otherwise.
    445      *
    446      * A default method is a public non-abstract instance method, that
    447      * is, a non-static method with a body, declared in an interface
    448      * type.
    449      *
    450      * @return true if and only if this method is a default
    451      * method as defined by the Java Language Specification.
    452      * @since 1.8
    453      */
    454     public boolean isDefault() {
    455         // Android-changed: This is handled by Executable.
    456         return super.isDefaultMethodInternal();
    457     }
    458 
    459     /**
    460      * Returns the default value for the annotation member represented by
    461      * this {@code Method} instance.  If the member is of a primitive type,
    462      * an instance of the corresponding wrapper type is returned. Returns
    463      * null if no default is associated with the member, or if the method
    464      * instance does not represent a declared member of an annotation type.
    465      *
    466      * @return the default value for the annotation member represented
    467      *     by this {@code Method} instance.
    468      * @throws TypeNotPresentException if the annotation is of type
    469      *     {@link Class} and no definition can be found for the
    470      *     default class value.
    471      * @since  1.5
    472      */
    473     @FastNative
    474     public native Object getDefaultValue();
    475 
    476     /**
    477      * {@inheritDoc}
    478      * @throws NullPointerException  {@inheritDoc}
    479      * @since 1.5
    480      */
    481     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
    482         return super.getAnnotation(annotationClass);
    483     }
    484 
    485     /**
    486      * {@inheritDoc}
    487      * @since 1.5
    488      */
    489     public Annotation[] getDeclaredAnnotations()  {
    490         return super.getDeclaredAnnotations();
    491     }
    492 
    493     /**
    494      * {@inheritDoc}
    495      * @since 1.5
    496      */
    497     @Override
    498     public Annotation[][] getParameterAnnotations() {
    499         // Android-changed: This is handled by Executable.
    500         return super.getParameterAnnotationsInternal();
    501     }
    502 
    503     /**
    504      * Returns true if this and {@code method} have the same name and the same
    505      * parameters in the same order. Such methods can share implementation if
    506      * one method's return types is assignable to the other.
    507      *
    508      * @hide needed by Proxy
    509      */
    510     boolean equalNameAndParameters(Method m) {
    511         return equalNameAndParametersInternal(m);
    512     }
    513 }
    514