44 * or an instance method (including an abstract method). 45 * 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. 50 * 51 * @see Member 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[]) 57 * 58 * @author Kenneth Russell 59 * @author Nakul Saraiya 60 */ 61 public final 62 class Method extends AccessibleObject implements GenericDeclaration, 63 Member { 64 private Class clazz; 65 private int slot; 66 // This is guaranteed to be interned by the VM in the 1.4 67 // reflection implementation 68 private String name; 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.) 84 private Method root; 85 86 // More complicated security check cache needed here than for 87 // Class.newInstance() and Constructor.newInstance() 88 private Class securityCheckCache; 89 private Class securityCheckTargetClassCache; 90 91 // Generics infrastructure 92 93 private String getGenericSignature() {return signature;} 94 95 // Accessor for factory 96 private GenericsFactory getFactory() { 97 // create scope and factory 98 return CoreReflectionFactory.make(this, MethodScope.make(this)); 99 } 100 101 // Accessor for generic info repository 102 private MethodRepository getGenericInfo() { 103 // lazily initialize repository if necessary 104 if (genericInfo == null) { 105 // create and cache generic info repository 106 genericInfo = MethodRepository.make(getGenericSignature(), 107 getFactory()); 108 } 109 return genericInfo; //return cached repository 110 } 111 112 /** 113 * Package-private constructor used by ReflectAccess to enable 114 * instantiation of these objects in Java code from the java.lang 115 * package via sun.reflect.LangReflectAccess. 116 */ 117 Method(Class declaringClass, 118 String name, 119 Class[] parameterTypes, 120 Class returnType, 121 Class[] checkedExceptions, 122 int modifiers, 123 int slot, 124 String signature, 125 byte[] annotations, 126 byte[] parameterAnnotations, 127 byte[] annotationDefault) 128 { 129 this.clazz = declaringClass; 130 this.name = name; 131 this.parameterTypes = parameterTypes; 132 this.returnType = returnType; 133 this.exceptionTypes = checkedExceptions; 134 this.modifiers = modifiers; 135 this.slot = slot; 136 this.signature = signature; 137 this.annotations = annotations; 138 this.parameterAnnotations = parameterAnnotations; 139 this.annotationDefault = annotationDefault; 140 } 141 338 ((result = getGenericInfo().getExceptionTypes()).length > 0)) 339 return result; 340 else 341 return getExceptionTypes(); 342 } 343 344 /** 345 * Compares this {@code Method} against the specified object. Returns 346 * true if the objects are the same. Two {@code Methods} are the same if 347 * they were declared by the same class and have the same name 348 * and formal parameter types and return type. 349 */ 350 public boolean equals(Object obj) { 351 if (obj != null && obj instanceof Method) { 352 Method other = (Method)obj; 353 if ((getDeclaringClass() == other.getDeclaringClass()) 354 && (getName() == other.getName())) { 355 if (!returnType.equals(other.getReturnType())) 356 return false; 357 /* Avoid unnecessary cloning */ 358 Class[] params1 = parameterTypes; 359 Class[] params2 = other.parameterTypes; 360 if (params1.length == params2.length) { 361 for (int i = 0; i < params1.length; i++) { 362 if (params1[i] != params2[i]) 363 return false; 364 } 365 return true; 366 } 367 } 368 } 369 return false; 370 } 371 372 /** 373 * Returns a hashcode for this {@code Method}. The hashcode is computed 374 * as the exclusive-or of the hashcodes for the underlying 375 * method's declaring class name and the method's name. 376 */ 377 public int hashCode() { 378 return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); 379 } 393 * public boolean java.lang.Object.equals(java.lang.Object) 394 * </pre> 395 * 396 * <p>The access modifiers are placed in canonical order as 397 * specified by "The Java Language Specification". This is 398 * {@code public}, {@code protected} or {@code private} first, 399 * and then other modifiers in the following order: 400 * {@code abstract}, {@code static}, {@code final}, 401 * {@code synchronized}, {@code native}, {@code strictfp}. 402 */ 403 public String toString() { 404 try { 405 StringBuffer sb = new StringBuffer(); 406 int mod = getModifiers() & Modifier.methodModifiers(); 407 if (mod != 0) { 408 sb.append(Modifier.toString(mod) + " "); 409 } 410 sb.append(Field.getTypeName(getReturnType()) + " "); 411 sb.append(Field.getTypeName(getDeclaringClass()) + "."); 412 sb.append(getName() + "("); 413 Class[] params = parameterTypes; // avoid clone 414 for (int j = 0; j < params.length; j++) { 415 sb.append(Field.getTypeName(params[j])); 416 if (j < (params.length - 1)) 417 sb.append(","); 418 } 419 sb.append(")"); 420 Class[] exceptions = exceptionTypes; // avoid clone 421 if (exceptions.length > 0) { 422 sb.append(" throws "); 423 for (int k = 0; k < exceptions.length; k++) { 424 sb.append(exceptions[k].getName()); 425 if (k < (exceptions.length - 1)) 426 sb.append(","); 427 } 428 } 429 return sb.toString(); 430 } catch (Exception e) { 431 return "<" + e + ">"; 432 } 433 } 434 435 /** 436 * Returns a string describing this {@code Method}, including 437 * type parameters. The string is formatted as the method access 438 * modifiers, if any, followed by an angle-bracketed 439 * comma-separated list of the method's type parameters, if any, 440 * followed by the method's generic return type, followed by a 573 * declaring the underlying method (or of a subclass 574 * or implementor thereof); if the number of actual 575 * and formal parameters differ; if an unwrapping 576 * conversion for primitive arguments fails; or if, 577 * after possible unwrapping, a parameter value 578 * cannot be converted to the corresponding formal 579 * parameter type by a method invocation conversion. 580 * @exception InvocationTargetException if the underlying method 581 * throws an exception. 582 * @exception NullPointerException if the specified object is null 583 * and the method is an instance method. 584 * @exception ExceptionInInitializerError if the initialization 585 * provoked by this method fails. 586 */ 587 public Object invoke(Object obj, Object... args) 588 throws IllegalAccessException, IllegalArgumentException, 589 InvocationTargetException 590 { 591 if (!override) { 592 if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { 593 Class caller = Reflection.getCallerClass(1); 594 Class targetClass = ((obj == null || !Modifier.isProtected(modifiers)) 595 ? clazz 596 : obj.getClass()); 597 598 boolean cached; 599 synchronized (this) { 600 cached = (securityCheckCache == caller) 601 && (securityCheckTargetClassCache == targetClass); 602 } 603 if (!cached) { 604 Reflection.ensureMemberAccess(caller, clazz, obj, modifiers); 605 synchronized (this) { 606 securityCheckCache = caller; 607 securityCheckTargetClassCache = targetClass; 608 } 609 } 610 } 611 } 612 if (methodAccessor == null) acquireMethodAccessor(); 613 return methodAccessor.invoke(obj, args); 614 } 685 } 686 687 /** 688 * @throws NullPointerException {@inheritDoc} 689 * @since 1.5 690 */ 691 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { 692 if (annotationClass == null) 693 throw new NullPointerException(); 694 695 return (T) declaredAnnotations().get(annotationClass); 696 } 697 698 /** 699 * @since 1.5 700 */ 701 public Annotation[] getDeclaredAnnotations() { 702 return AnnotationParser.toArray(declaredAnnotations()); 703 } 704 705 private transient Map<Class, Annotation> declaredAnnotations; 706 707 private synchronized Map<Class, Annotation> declaredAnnotations() { 708 if (declaredAnnotations == null) { 709 declaredAnnotations = AnnotationParser.parseAnnotations( 710 annotations, sun.misc.SharedSecrets.getJavaLangAccess(). 711 getConstantPool(getDeclaringClass()), 712 getDeclaringClass()); 713 } 714 return declaredAnnotations; 715 } 716 717 /** 718 * Returns the default value for the annotation member represented by 719 * this {@code Method} instance. If the member is of a primitive type, 720 * an instance of the corresponding wrapper type is returned. Returns 721 * null if no default is associated with the member, or if the method 722 * instance does not represent a declared member of an annotation type. 723 * 724 * @return the default value for the annotation member represented 725 * by this {@code Method} instance. 726 * @throws TypeNotPresentException if the annotation is of type 727 * {@link Class} and no definition can be found for the 728 * default class value. 729 * @since 1.5 730 */ 731 public Object getDefaultValue() { 732 if (annotationDefault == null) 733 return null; 734 Class memberType = AnnotationType.invocationHandlerReturnType( 735 getReturnType()); 736 Object result = AnnotationParser.parseMemberValue( 737 memberType, ByteBuffer.wrap(annotationDefault), 738 sun.misc.SharedSecrets.getJavaLangAccess(). 739 getConstantPool(getDeclaringClass()), 740 getDeclaringClass()); 741 if (result instanceof sun.reflect.annotation.ExceptionProxy) 742 throw new AnnotationFormatError("Invalid default: " + this); 743 return result; 744 } 745 746 /** 747 * Returns an array of arrays that represent the annotations on the formal 748 * parameters, in declaration order, of the method represented by 749 * this {@code Method} object. (Returns an array of length zero if the 750 * underlying method is parameterless. If the method has one or more 751 * parameters, a nested array of length zero is returned for each parameter 752 * with no annotations.) The annotation objects contained in the returned 753 * arrays are serializable. The caller of this method is free to modify 754 * the returned arrays; it will have no effect on the arrays returned to | 44 * or an instance method (including an abstract method). 45 * 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. 50 * 51 * @see Member 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[]) 57 * 58 * @author Kenneth Russell 59 * @author Nakul Saraiya 60 */ 61 public final 62 class Method extends AccessibleObject implements GenericDeclaration, 63 Member { 64 private Class<?> clazz; 65 private int slot; 66 // This is guaranteed to be interned by the VM in the 1.4 67 // reflection implementation 68 private String name; 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.) 84 private Method root; 85 86 // More complicated security check cache needed here than for 87 // Class.newInstance() and Constructor.newInstance() 88 private Class<?> securityCheckCache; 89 private Class<?> securityCheckTargetClassCache; 90 91 // Generics infrastructure 92 93 private String getGenericSignature() {return signature;} 94 95 // Accessor for factory 96 private GenericsFactory getFactory() { 97 // create scope and factory 98 return CoreReflectionFactory.make(this, MethodScope.make(this)); 99 } 100 101 // Accessor for generic info repository 102 private MethodRepository getGenericInfo() { 103 // lazily initialize repository if necessary 104 if (genericInfo == null) { 105 // create and cache generic info repository 106 genericInfo = MethodRepository.make(getGenericSignature(), 107 getFactory()); 108 } 109 return genericInfo; //return cached repository 110 } 111 112 /** 113 * Package-private constructor used by ReflectAccess to enable 114 * instantiation of these objects in Java code from the java.lang 115 * package via sun.reflect.LangReflectAccess. 116 */ 117 Method(Class<?> declaringClass, 118 String name, 119 Class<?>[] parameterTypes, 120 Class<?> returnType, 121 Class<?>[] checkedExceptions, 122 int modifiers, 123 int slot, 124 String signature, 125 byte[] annotations, 126 byte[] parameterAnnotations, 127 byte[] annotationDefault) 128 { 129 this.clazz = declaringClass; 130 this.name = name; 131 this.parameterTypes = parameterTypes; 132 this.returnType = returnType; 133 this.exceptionTypes = checkedExceptions; 134 this.modifiers = modifiers; 135 this.slot = slot; 136 this.signature = signature; 137 this.annotations = annotations; 138 this.parameterAnnotations = parameterAnnotations; 139 this.annotationDefault = annotationDefault; 140 } 141 338 ((result = getGenericInfo().getExceptionTypes()).length > 0)) 339 return result; 340 else 341 return getExceptionTypes(); 342 } 343 344 /** 345 * Compares this {@code Method} against the specified object. Returns 346 * true if the objects are the same. Two {@code Methods} are the same if 347 * they were declared by the same class and have the same name 348 * and formal parameter types and return type. 349 */ 350 public boolean equals(Object obj) { 351 if (obj != null && obj instanceof Method) { 352 Method other = (Method)obj; 353 if ((getDeclaringClass() == other.getDeclaringClass()) 354 && (getName() == other.getName())) { 355 if (!returnType.equals(other.getReturnType())) 356 return false; 357 /* Avoid unnecessary cloning */ 358 Class<?>[] params1 = parameterTypes; 359 Class<?>[] params2 = other.parameterTypes; 360 if (params1.length == params2.length) { 361 for (int i = 0; i < params1.length; i++) { 362 if (params1[i] != params2[i]) 363 return false; 364 } 365 return true; 366 } 367 } 368 } 369 return false; 370 } 371 372 /** 373 * Returns a hashcode for this {@code Method}. The hashcode is computed 374 * as the exclusive-or of the hashcodes for the underlying 375 * method's declaring class name and the method's name. 376 */ 377 public int hashCode() { 378 return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); 379 } 393 * public boolean java.lang.Object.equals(java.lang.Object) 394 * </pre> 395 * 396 * <p>The access modifiers are placed in canonical order as 397 * specified by "The Java Language Specification". This is 398 * {@code public}, {@code protected} or {@code private} first, 399 * and then other modifiers in the following order: 400 * {@code abstract}, {@code static}, {@code final}, 401 * {@code synchronized}, {@code native}, {@code strictfp}. 402 */ 403 public String toString() { 404 try { 405 StringBuffer sb = new StringBuffer(); 406 int mod = getModifiers() & Modifier.methodModifiers(); 407 if (mod != 0) { 408 sb.append(Modifier.toString(mod) + " "); 409 } 410 sb.append(Field.getTypeName(getReturnType()) + " "); 411 sb.append(Field.getTypeName(getDeclaringClass()) + "."); 412 sb.append(getName() + "("); 413 Class<?>[] params = parameterTypes; // avoid clone 414 for (int j = 0; j < params.length; j++) { 415 sb.append(Field.getTypeName(params[j])); 416 if (j < (params.length - 1)) 417 sb.append(","); 418 } 419 sb.append(")"); 420 Class<?>[] exceptions = exceptionTypes; // avoid clone 421 if (exceptions.length > 0) { 422 sb.append(" throws "); 423 for (int k = 0; k < exceptions.length; k++) { 424 sb.append(exceptions[k].getName()); 425 if (k < (exceptions.length - 1)) 426 sb.append(","); 427 } 428 } 429 return sb.toString(); 430 } catch (Exception e) { 431 return "<" + e + ">"; 432 } 433 } 434 435 /** 436 * Returns a string describing this {@code Method}, including 437 * type parameters. The string is formatted as the method access 438 * modifiers, if any, followed by an angle-bracketed 439 * comma-separated list of the method's type parameters, if any, 440 * followed by the method's generic return type, followed by a 573 * declaring the underlying method (or of a subclass 574 * or implementor thereof); if the number of actual 575 * and formal parameters differ; if an unwrapping 576 * conversion for primitive arguments fails; or if, 577 * after possible unwrapping, a parameter value 578 * cannot be converted to the corresponding formal 579 * parameter type by a method invocation conversion. 580 * @exception InvocationTargetException if the underlying method 581 * throws an exception. 582 * @exception NullPointerException if the specified object is null 583 * and the method is an instance method. 584 * @exception ExceptionInInitializerError if the initialization 585 * provoked by this method fails. 586 */ 587 public Object invoke(Object obj, Object... args) 588 throws IllegalAccessException, IllegalArgumentException, 589 InvocationTargetException 590 { 591 if (!override) { 592 if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { 593 Class<?> caller = Reflection.getCallerClass(1); 594 Class<?> targetClass = ((obj == null || !Modifier.isProtected(modifiers)) 595 ? clazz 596 : obj.getClass()); 597 598 boolean cached; 599 synchronized (this) { 600 cached = (securityCheckCache == caller) 601 && (securityCheckTargetClassCache == targetClass); 602 } 603 if (!cached) { 604 Reflection.ensureMemberAccess(caller, clazz, obj, modifiers); 605 synchronized (this) { 606 securityCheckCache = caller; 607 securityCheckTargetClassCache = targetClass; 608 } 609 } 610 } 611 } 612 if (methodAccessor == null) acquireMethodAccessor(); 613 return methodAccessor.invoke(obj, args); 614 } 685 } 686 687 /** 688 * @throws NullPointerException {@inheritDoc} 689 * @since 1.5 690 */ 691 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { 692 if (annotationClass == null) 693 throw new NullPointerException(); 694 695 return (T) declaredAnnotations().get(annotationClass); 696 } 697 698 /** 699 * @since 1.5 700 */ 701 public Annotation[] getDeclaredAnnotations() { 702 return AnnotationParser.toArray(declaredAnnotations()); 703 } 704 705 private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations; 706 707 private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() { 708 if (declaredAnnotations == null) { 709 declaredAnnotations = AnnotationParser.parseAnnotations( 710 annotations, sun.misc.SharedSecrets.getJavaLangAccess(). 711 getConstantPool(getDeclaringClass()), 712 getDeclaringClass()); 713 } 714 return declaredAnnotations; 715 } 716 717 /** 718 * Returns the default value for the annotation member represented by 719 * this {@code Method} instance. If the member is of a primitive type, 720 * an instance of the corresponding wrapper type is returned. Returns 721 * null if no default is associated with the member, or if the method 722 * instance does not represent a declared member of an annotation type. 723 * 724 * @return the default value for the annotation member represented 725 * by this {@code Method} instance. 726 * @throws TypeNotPresentException if the annotation is of type 727 * {@link Class} and no definition can be found for the 728 * default class value. 729 * @since 1.5 730 */ 731 public Object getDefaultValue() { 732 if (annotationDefault == null) 733 return null; 734 Class<?> memberType = AnnotationType.invocationHandlerReturnType( 735 getReturnType()); 736 Object result = AnnotationParser.parseMemberValue( 737 memberType, ByteBuffer.wrap(annotationDefault), 738 sun.misc.SharedSecrets.getJavaLangAccess(). 739 getConstantPool(getDeclaringClass()), 740 getDeclaringClass()); 741 if (result instanceof sun.reflect.annotation.ExceptionProxy) 742 throw new AnnotationFormatError("Invalid default: " + this); 743 return result; 744 } 745 746 /** 747 * Returns an array of arrays that represent the annotations on the formal 748 * parameters, in declaration order, of the method represented by 749 * this {@code Method} object. (Returns an array of length zero if the 750 * underlying method is parameterless. If the method has one or more 751 * parameters, a nested array of length zero is returned for each parameter 752 * with no annotations.) The annotation objects contained in the returned 753 * arrays are serializable. The caller of this method is free to modify 754 * the returned arrays; it will have no effect on the arrays returned to |