2 * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
26 package java.lang.reflect;
28 import sun.reflect.MethodAccessor;
29 import sun.reflect.Reflection;
30 import sun.reflect.generics.repository.MethodRepository;
31 import sun.reflect.generics.factory.CoreReflectionFactory;
32 import sun.reflect.generics.factory.GenericsFactory;
33 import sun.reflect.generics.scope.MethodScope;
34 import sun.reflect.annotation.AnnotationType;
35 import sun.reflect.annotation.AnnotationParser;
36 import java.lang.annotation.Annotation;
37 import java.lang.annotation.AnnotationFormatError;
38 import java.nio.ByteBuffer;
42 * A {@code Method} provides information about, and access to, a single method
43 * on a class or interface. The reflected method may be a class method
44 * or an instance method (including an abstract method).
46 * <p>A {@code Method} permits widening conversions to occur when matching the
47 * actual parameters to invoke with the underlying method's formal
48 * parameters, but it throws an {@code IllegalArgumentException} if a
49 * narrowing conversion would occur.
52 * @see java.lang.Class
53 * @see java.lang.Class#getMethods()
54 * @see java.lang.Class#getMethod(String, Class[])
55 * @see java.lang.Class#getDeclaredMethods()
56 * @see java.lang.Class#getDeclaredMethod(String, Class[])
58 * @author Kenneth Russell
59 * @author Nakul Saraiya
62 class Method extends AccessibleObject implements GenericDeclaration,
64 private Class<?> clazz;
66 // This is guaranteed to be interned by the VM in the 1.4
67 // reflection implementation
69 private Class<?> returnType;
70 private Class<?>[] parameterTypes;
71 private Class<?>[] exceptionTypes;
72 private int modifiers;
73 // Generics and annotations support
74 private transient String signature;
75 // generic info repository; lazily initialized
76 private transient MethodRepository genericInfo;
77 private byte[] annotations;
78 private byte[] parameterAnnotations;
79 private byte[] annotationDefault;
80 private volatile MethodAccessor methodAccessor;
81 // For sharing of MethodAccessors. This branching structure is
82 // currently only two levels deep (i.e., one root Method and
83 // potentially many Method objects pointing to it.)
86 // Generics infrastructure
88 private String getGenericSignature() {return signature;}
90 // Accessor for factory
91 private GenericsFactory getFactory() {
92 // create scope and factory
93 return CoreReflectionFactory.make(this, MethodScope.make(this));
96 // Accessor for generic info repository
97 private MethodRepository getGenericInfo() {
98 // lazily initialize repository if necessary
99 if (genericInfo == null) {
100 // create and cache generic info repository
101 genericInfo = MethodRepository.make(getGenericSignature(),
104 return genericInfo; //return cached repository
108 * Package-private constructor used by ReflectAccess to enable
109 * instantiation of these objects in Java code from the java.lang
110 * package via sun.reflect.LangReflectAccess.
112 Method(Class<?> declaringClass,
114 Class<?>[] parameterTypes,
116 Class<?>[] checkedExceptions,
121 byte[] parameterAnnotations,
122 byte[] annotationDefault)
124 this.clazz = declaringClass;
126 this.parameterTypes = parameterTypes;
127 this.returnType = returnType;
128 this.exceptionTypes = checkedExceptions;
129 this.modifiers = modifiers;
131 this.signature = signature;
132 this.annotations = annotations;
133 this.parameterAnnotations = parameterAnnotations;
134 this.annotationDefault = annotationDefault;
138 * Package-private routine (exposed to java.lang.Class via
139 * ReflectAccess) which returns a copy of this Method. The copy's
140 * "root" field points to this Method.
143 // This routine enables sharing of MethodAccessor objects
144 // among Method objects which refer to the same underlying
145 // method in the VM. (All of this contortion is only necessary
146 // because of the "accessibility" bit in AccessibleObject,
147 // which implicitly requires that new java.lang.reflect
148 // objects be fabricated for each reflective call on Class
150 Method res = new Method(clazz, name, parameterTypes, returnType,
151 exceptionTypes, modifiers, slot, signature,
152 annotations, parameterAnnotations, annotationDefault);
154 // Might as well eagerly propagate this if already present
155 res.methodAccessor = methodAccessor;
160 * Returns the {@code Class} object representing the class or interface
161 * that declares the method represented by this {@code Method} object.
163 public Class<?> getDeclaringClass() {
168 * Returns the name of the method represented by this {@code Method}
169 * object, as a {@code String}.
171 public String getName() {
176 * Returns the Java language modifiers for the method represented
177 * by this {@code Method} object, as an integer. The {@code Modifier} class should
178 * be used to decode the modifiers.
182 public int getModifiers() {
187 * Returns an array of {@code TypeVariable} objects that represent the
188 * type variables declared by the generic declaration represented by this
189 * {@code GenericDeclaration} object, in declaration order. Returns an
190 * array of length 0 if the underlying generic declaration declares no type
193 * @return an array of {@code TypeVariable} objects that represent
194 * the type variables declared by this generic declaration
195 * @throws GenericSignatureFormatError if the generic
196 * signature of this generic declaration does not conform to
197 * the format specified in
198 * <cite>The Java™ Virtual Machine Specification</cite>
201 public TypeVariable<Method>[] getTypeParameters() {
202 if (getGenericSignature() != null)
203 return (TypeVariable<Method>[])getGenericInfo().getTypeParameters();
205 return (TypeVariable<Method>[])new TypeVariable[0];
209 * Returns a {@code Class} object that represents the formal return type
210 * of the method represented by this {@code Method} object.
212 * @return the return type for the method this object represents
214 public Class<?> getReturnType() {
219 * Returns a {@code Type} object that represents the formal return
220 * type of the method represented by this {@code Method} object.
222 * <p>If the return type is a parameterized type,
223 * the {@code Type} object returned must accurately reflect
224 * the actual type parameters used in the source code.
226 * <p>If the return type is a type variable or a parameterized type, it
227 * is created. Otherwise, it is resolved.
229 * @return a {@code Type} object that represents the formal return
230 * type of the underlying method
231 * @throws GenericSignatureFormatError
232 * if the generic method signature does not conform to the format
234 * <cite>The Java™ Virtual Machine Specification</cite>
235 * @throws TypeNotPresentException if the underlying method's
236 * return type refers to a non-existent type declaration
237 * @throws MalformedParameterizedTypeException if the
238 * underlying method's return typed refers to a parameterized
239 * type that cannot be instantiated for any reason
242 public Type getGenericReturnType() {
243 if (getGenericSignature() != null) {
244 return getGenericInfo().getReturnType();
245 } else { return getReturnType();}
250 * Returns an array of {@code Class} objects that represent the formal
251 * parameter types, in declaration order, of the method
252 * represented by this {@code Method} object. Returns an array of length
253 * 0 if the underlying method takes no parameters.
255 * @return the parameter types for the method this object
258 public Class<?>[] getParameterTypes() {
259 return (Class<?>[]) parameterTypes.clone();
263 * Returns an array of {@code Type} objects that represent the formal
264 * parameter types, in declaration order, of the method represented by
265 * this {@code Method} object. Returns an array of length 0 if the
266 * underlying method takes no parameters.
268 * <p>If a formal parameter type is a parameterized type,
269 * the {@code Type} object returned for it must accurately reflect
270 * the actual type parameters used in the source code.
272 * <p>If a formal parameter type is a type variable or a parameterized
273 * type, it is created. Otherwise, it is resolved.
275 * @return an array of Types that represent the formal
276 * parameter types of the underlying method, in declaration order
277 * @throws GenericSignatureFormatError
278 * if the generic method signature does not conform to the format
280 * <cite>The Java™ Virtual Machine Specification</cite>
281 * @throws TypeNotPresentException if any of the parameter
282 * types of the underlying method refers to a non-existent type
284 * @throws MalformedParameterizedTypeException if any of
285 * the underlying method's parameter types refer to a parameterized
286 * type that cannot be instantiated for any reason
289 public Type[] getGenericParameterTypes() {
290 if (getGenericSignature() != null)
291 return getGenericInfo().getParameterTypes();
293 return getParameterTypes();
298 * Returns an array of {@code Class} objects that represent
299 * the types of the exceptions declared to be thrown
300 * by the underlying method
301 * represented by this {@code Method} object. Returns an array of length
302 * 0 if the method declares no exceptions in its {@code throws} clause.
304 * @return the exception types declared as being thrown by the
305 * method this object represents
307 public Class<?>[] getExceptionTypes() {
308 return (Class<?>[]) exceptionTypes.clone();
312 * Returns an array of {@code Type} objects that represent the
313 * exceptions declared to be thrown by this {@code Method} object.
314 * Returns an array of length 0 if the underlying method declares
315 * no exceptions in its {@code throws} clause.
317 * <p>If an exception type is a type variable or a parameterized
318 * type, it is created. Otherwise, it is resolved.
320 * @return an array of Types that represent the exception types
321 * thrown by the underlying method
322 * @throws GenericSignatureFormatError
323 * if the generic method signature does not conform to the format
325 * <cite>The Java™ Virtual Machine Specification</cite>
326 * @throws TypeNotPresentException if the underlying method's
327 * {@code throws} clause refers to a non-existent type declaration
328 * @throws MalformedParameterizedTypeException if
329 * the underlying method's {@code throws} clause refers to a
330 * parameterized type that cannot be instantiated for any reason
333 public Type[] getGenericExceptionTypes() {
335 if (getGenericSignature() != null &&
336 ((result = getGenericInfo().getExceptionTypes()).length > 0))
339 return getExceptionTypes();
343 * Compares this {@code Method} against the specified object. Returns
344 * true if the objects are the same. Two {@code Methods} are the same if
345 * they were declared by the same class and have the same name
346 * and formal parameter types and return type.
348 public boolean equals(Object obj) {
349 if (obj != null && obj instanceof Method) {
350 Method other = (Method)obj;
351 if ((getDeclaringClass() == other.getDeclaringClass())
352 && (getName() == other.getName())) {
353 if (!returnType.equals(other.getReturnType()))
355 /* Avoid unnecessary cloning */
356 Class<?>[] params1 = parameterTypes;
357 Class<?>[] params2 = other.parameterTypes;
358 if (params1.length == params2.length) {
359 for (int i = 0; i < params1.length; i++) {
360 if (params1[i] != params2[i])
371 * Returns a hashcode for this {@code Method}. The hashcode is computed
372 * as the exclusive-or of the hashcodes for the underlying
373 * method's declaring class name and the method's name.
375 public int hashCode() {
376 return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
380 * Returns a string describing this {@code Method}. The string is
381 * formatted as the method access modifiers, if any, followed by
382 * the method return type, followed by a space, followed by the
383 * class declaring the method, followed by a period, followed by
384 * the method name, followed by a parenthesized, comma-separated
385 * list of the method's formal parameter types. If the method
386 * throws checked exceptions, the parameter list is followed by a
387 * space, followed by the word throws followed by a
388 * comma-separated list of the thrown exception types.
391 * public boolean java.lang.Object.equals(java.lang.Object)
394 * <p>The access modifiers are placed in canonical order as
395 * specified by "The Java Language Specification". This is
396 * {@code public}, {@code protected} or {@code private} first,
397 * and then other modifiers in the following order:
398 * {@code abstract}, {@code static}, {@code final},
399 * {@code synchronized}, {@code native}, {@code strictfp}.
401 public String toString() {
403 StringBuilder sb = new StringBuilder();
404 int mod = getModifiers() & Modifier.methodModifiers();
406 sb.append(Modifier.toString(mod)).append(' ');
408 sb.append(Field.getTypeName(getReturnType())).append(' ');
409 sb.append(Field.getTypeName(getDeclaringClass())).append('.');
410 sb.append(getName()).append('(');
411 Class<?>[] params = parameterTypes; // avoid clone
412 for (int j = 0; j < params.length; j++) {
413 sb.append(Field.getTypeName(params[j]));
414 if (j < (params.length - 1))
418 Class<?>[] exceptions = exceptionTypes; // avoid clone
419 if (exceptions.length > 0) {
420 sb.append(" throws ");
421 for (int k = 0; k < exceptions.length; k++) {
422 sb.append(exceptions[k].getName());
423 if (k < (exceptions.length - 1))
427 return sb.toString();
428 } catch (Exception e) {
429 return "<" + e + ">";
434 * Returns a string describing this {@code Method}, including
435 * type parameters. The string is formatted as the method access
436 * modifiers, if any, followed by an angle-bracketed
437 * comma-separated list of the method's type parameters, if any,
438 * followed by the method's generic return type, followed by a
439 * space, followed by the class declaring the method, followed by
440 * a period, followed by the method name, followed by a
441 * parenthesized, comma-separated list of the method's generic
442 * formal parameter types.
444 * If this method was declared to take a variable number of
445 * arguments, instead of denoting the last parameter as
446 * "<tt><i>Type</i>[]</tt>", it is denoted as
447 * "<tt><i>Type</i>...</tt>".
449 * A space is used to separate access modifiers from one another
450 * and from the type parameters or return type. If there are no
451 * type parameters, the type parameter list is elided; if the type
452 * parameter list is present, a space separates the list from the
453 * class name. If the method is declared to throw exceptions, the
454 * parameter list is followed by a space, followed by the word
455 * throws followed by a comma-separated list of the generic thrown
456 * exception types. If there are no type parameters, the type
457 * parameter list is elided.
459 * <p>The access modifiers are placed in canonical order as
460 * specified by "The Java Language Specification". This is
461 * {@code public}, {@code protected} or {@code private} first,
462 * and then other modifiers in the following order:
463 * {@code abstract}, {@code static}, {@code final},
464 * {@code synchronized}, {@code native}, {@code strictfp}.
466 * @return a string describing this {@code Method},
467 * include type parameters
471 public String toGenericString() {
473 StringBuilder sb = new StringBuilder();
474 int mod = getModifiers() & Modifier.methodModifiers();
476 sb.append(Modifier.toString(mod)).append(' ');
478 TypeVariable<?>[] typeparms = getTypeParameters();
479 if (typeparms.length > 0) {
480 boolean first = true;
482 for(TypeVariable<?> typeparm: typeparms) {
485 // Class objects can't occur here; no need to test
486 // and call Class.getName().
487 sb.append(typeparm.toString());
493 Type genRetType = getGenericReturnType();
494 sb.append( ((genRetType instanceof Class<?>)?
495 Field.getTypeName((Class<?>)genRetType):genRetType.toString()))
498 sb.append(Field.getTypeName(getDeclaringClass())).append('.');
499 sb.append(getName()).append('(');
500 Type[] params = getGenericParameterTypes();
501 for (int j = 0; j < params.length; j++) {
502 String param = (params[j] instanceof Class)?
503 Field.getTypeName((Class)params[j]):
504 (params[j].toString());
505 if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
506 param = param.replaceFirst("\\[\\]$", "...");
508 if (j < (params.length - 1))
512 Type[] exceptions = getGenericExceptionTypes();
513 if (exceptions.length > 0) {
514 sb.append(" throws ");
515 for (int k = 0; k < exceptions.length; k++) {
516 sb.append((exceptions[k] instanceof Class)?
517 ((Class)exceptions[k]).getName():
518 exceptions[k].toString());
519 if (k < (exceptions.length - 1))
523 return sb.toString();
524 } catch (Exception e) {
525 return "<" + e + ">";
530 * Invokes the underlying method represented by this {@code Method}
531 * object, on the specified object with the specified parameters.
532 * Individual parameters are automatically unwrapped to match
533 * primitive formal parameters, and both primitive and reference
534 * parameters are subject to method invocation conversions as
537 * <p>If the underlying method is static, then the specified {@code obj}
538 * argument is ignored. It may be null.
540 * <p>If the number of formal parameters required by the underlying method is
541 * 0, the supplied {@code args} array may be of length 0 or null.
543 * <p>If the underlying method is an instance method, it is invoked
544 * using dynamic method lookup as documented in The Java Language
545 * Specification, Second Edition, section 15.12.4.4; in particular,
546 * overriding based on the runtime type of the target object will occur.
548 * <p>If the underlying method is static, the class that declared
549 * the method is initialized if it has not already been initialized.
551 * <p>If the method completes normally, the value it returns is
552 * returned to the caller of invoke; if the value has a primitive
553 * type, it is first appropriately wrapped in an object. However,
554 * if the value has the type of an array of a primitive type, the
555 * elements of the array are <i>not</i> wrapped in objects; in
556 * other words, an array of primitive type is returned. If the
557 * underlying method return type is void, the invocation returns
560 * @param obj the object the underlying method is invoked from
561 * @param args the arguments used for the method call
562 * @return the result of dispatching the method represented by
563 * this object on {@code obj} with parameters
566 * @exception IllegalAccessException if this {@code Method} object
567 * is enforcing Java language access control and the underlying
568 * method is inaccessible.
569 * @exception IllegalArgumentException if the method is an
570 * instance method and the specified object argument
571 * is not an instance of the class or interface
572 * declaring the underlying method (or of a subclass
573 * or implementor thereof); if the number of actual
574 * and formal parameters differ; if an unwrapping
575 * conversion for primitive arguments fails; or if,
576 * after possible unwrapping, a parameter value
577 * cannot be converted to the corresponding formal
578 * parameter type by a method invocation conversion.
579 * @exception InvocationTargetException if the underlying method
580 * throws an exception.
581 * @exception NullPointerException if the specified object is null
582 * and the method is an instance method.
583 * @exception ExceptionInInitializerError if the initialization
584 * provoked by this method fails.
586 public Object invoke(Object obj, Object... args)
587 throws IllegalAccessException, IllegalArgumentException,
588 InvocationTargetException
591 if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
592 Class<?> caller = Reflection.getCallerClass(1);
594 checkAccess(caller, clazz, obj, modifiers);
597 MethodAccessor ma = methodAccessor; // read volatile
599 ma = acquireMethodAccessor();
601 return ma.invoke(obj, args);
605 * Returns {@code true} if this method is a bridge
606 * method; returns {@code false} otherwise.
608 * @return true if and only if this method is a bridge
609 * method as defined by the Java Language Specification.
612 public boolean isBridge() {
613 return (getModifiers() & Modifier.BRIDGE) != 0;
617 * Returns {@code true} if this method was declared to take
618 * a variable number of arguments; returns {@code false}
621 * @return {@code true} if an only if this method was declared to
622 * take a variable number of arguments.
625 public boolean isVarArgs() {
626 return (getModifiers() & Modifier.VARARGS) != 0;
630 * Returns {@code true} if this method is a synthetic
631 * method; returns {@code false} otherwise.
633 * @return true if and only if this method is a synthetic
634 * method as defined by the Java Language Specification.
637 public boolean isSynthetic() {
638 return Modifier.isSynthetic(getModifiers());
641 // NOTE that there is no synchronization used here. It is correct
642 // (though not efficient) to generate more than one MethodAccessor
643 // for a given Method. However, avoiding synchronization will
644 // probably make the implementation more scalable.
645 private MethodAccessor acquireMethodAccessor() {
646 // First check to see if one has been created yet, and take it
648 MethodAccessor tmp = null;
649 if (root != null) tmp = root.getMethodAccessor();
651 methodAccessor = tmp;
653 // Otherwise fabricate one and propagate it up to the root
654 tmp = reflectionFactory.newMethodAccessor(this);
655 setMethodAccessor(tmp);
661 // Returns MethodAccessor for this Method object, not looking up
662 // the chain to the root
663 MethodAccessor getMethodAccessor() {
664 return methodAccessor;
667 // Sets the MethodAccessor for this Method object and
668 // (recursively) its root
669 void setMethodAccessor(MethodAccessor accessor) {
670 methodAccessor = accessor;
673 root.setMethodAccessor(accessor);
678 * @throws NullPointerException {@inheritDoc}
681 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
682 if (annotationClass == null)
683 throw new NullPointerException();
685 return (T) declaredAnnotations().get(annotationClass);
691 public Annotation[] getDeclaredAnnotations() {
692 return AnnotationParser.toArray(declaredAnnotations());
695 private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
697 private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
698 if (declaredAnnotations == null) {
699 declaredAnnotations = AnnotationParser.parseAnnotations(
700 annotations, sun.misc.SharedSecrets.getJavaLangAccess().
701 getConstantPool(getDeclaringClass()),
702 getDeclaringClass());
704 return declaredAnnotations;
708 * Returns the default value for the annotation member represented by
709 * this {@code Method} instance. If the member is of a primitive type,
710 * an instance of the corresponding wrapper type is returned. Returns
711 * null if no default is associated with the member, or if the method
712 * instance does not represent a declared member of an annotation type.
714 * @return the default value for the annotation member represented
715 * by this {@code Method} instance.
716 * @throws TypeNotPresentException if the annotation is of type
717 * {@link Class} and no definition can be found for the
718 * default class value.
721 public Object getDefaultValue() {
722 if (annotationDefault == null)
724 Class<?> memberType = AnnotationType.invocationHandlerReturnType(
726 Object result = AnnotationParser.parseMemberValue(
727 memberType, ByteBuffer.wrap(annotationDefault),
728 sun.misc.SharedSecrets.getJavaLangAccess().
729 getConstantPool(getDeclaringClass()),
730 getDeclaringClass());
731 if (result instanceof sun.reflect.annotation.ExceptionProxy)
732 throw new AnnotationFormatError("Invalid default: " + this);
737 * Returns an array of arrays that represent the annotations on the formal
738 * parameters, in declaration order, of the method represented by
739 * this {@code Method} object. (Returns an array of length zero if the
740 * underlying method is parameterless. If the method has one or more
741 * parameters, a nested array of length zero is returned for each parameter
742 * with no annotations.) The annotation objects contained in the returned
743 * arrays are serializable. The caller of this method is free to modify
744 * the returned arrays; it will have no effect on the arrays returned to
747 * @return an array of arrays that represent the annotations on the formal
748 * parameters, in declaration order, of the method represented by this
752 public Annotation[][] getParameterAnnotations() {
753 int numParameters = parameterTypes.length;
754 if (parameterAnnotations == null)
755 return new Annotation[numParameters][0];
757 Annotation[][] result = AnnotationParser.parseParameterAnnotations(
758 parameterAnnotations,
759 sun.misc.SharedSecrets.getJavaLangAccess().
760 getConstantPool(getDeclaringClass()),
761 getDeclaringClass());
762 if (result.length != numParameters)
763 throw new java.lang.annotation.AnnotationFormatError(
764 "Parameter annotations don't match number of parameters");