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