src/share/classes/java/lang/reflect/Method.java

Print this page
rev 3746 : [mq]: cr6565585.ao


  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     }


 385      * class declaring the method, followed by a period, followed by
 386      * the method name, followed by a parenthesized, comma-separated
 387      * list of the method's formal parameter types. If the method
 388      * throws checked exceptions, the parameter list is followed by a
 389      * space, followed by the word throws followed by a
 390      * comma-separated list of the thrown exception types.
 391      * For example:
 392      * <pre>
 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
 441      * space, followed by the class declaring the method, followed by
 442      * a period, followed by the method name, followed by a
 443      * parenthesized, comma-separated list of the method's generic
 444      * formal parameter types.
 445      *
 446      * If this method was declared to take a variable number of


 458      * exception types.  If there are no type parameters, the type
 459      * parameter list is elided.
 460      *
 461      * <p>The access modifiers are placed in canonical order as
 462      * specified by "The Java Language Specification".  This is
 463      * {@code public}, {@code protected} or {@code private} first,
 464      * and then other modifiers in the following order:
 465      * {@code abstract}, {@code static}, {@code final},
 466      * {@code synchronized}, {@code native}, {@code strictfp}.
 467      *
 468      * @return a string describing this {@code Method},
 469      * include type parameters
 470      *
 471      * @since 1.5
 472      */
 473     public String toGenericString() {
 474         try {
 475             StringBuilder sb = new StringBuilder();
 476             int mod = getModifiers() & Modifier.methodModifiers();
 477             if (mod != 0) {
 478                 sb.append(Modifier.toString(mod) + " ");
 479             }
 480             TypeVariable<?>[] typeparms = getTypeParameters();
 481             if (typeparms.length > 0) {
 482                 boolean first = true;
 483                 sb.append("<");
 484                 for(TypeVariable<?> typeparm: typeparms) {
 485                     if (!first)
 486                         sb.append(",");
 487                     // Class objects can't occur here; no need to test
 488                     // and call Class.getName().
 489                     sb.append(typeparm.toString());
 490                     first = false;
 491                 }
 492                 sb.append("> ");
 493             }
 494 
 495             Type genRetType = getGenericReturnType();
 496             sb.append( ((genRetType instanceof Class<?>)?
 497                         Field.getTypeName((Class<?>)genRetType):genRetType.toString())  + " ");

 498 
 499             sb.append(Field.getTypeName(getDeclaringClass()) + ".");
 500             sb.append(getName() + "(");
 501             Type[] params = getGenericParameterTypes();
 502             for (int j = 0; j < params.length; j++) {
 503                 String param = (params[j] instanceof Class)?
 504                     Field.getTypeName((Class)params[j]):
 505                     (params[j].toString());
 506                 if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
 507                     param = param.replaceFirst("\\[\\]$", "...");
 508                 sb.append(param);
 509                 if (j < (params.length - 1))
 510                     sb.append(",");
 511             }
 512             sb.append(")");
 513             Type[] exceptions = getGenericExceptionTypes();
 514             if (exceptions.length > 0) {
 515                 sb.append(" throws ");
 516                 for (int k = 0; k < exceptions.length; k++) {
 517                     sb.append((exceptions[k] instanceof Class)?
 518                               ((Class)exceptions[k]).getName():
 519                               exceptions[k].toString());
 520                     if (k < (exceptions.length - 1))
 521                         sb.append(",");
 522                 }
 523             }
 524             return sb.toString();
 525         } catch (Exception e) {
 526             return "<" + e + ">";
 527         }
 528     }
 529 
 530     /**
 531      * Invokes the underlying method represented by this {@code Method}
 532      * object, on the specified object with the specified parameters.
 533      * Individual parameters are automatically unwrapped to match
 534      * primitive formal parameters, and both primitive and reference
 535      * parameters are subject to method invocation conversions as
 536      * necessary.
 537      *
 538      * <p>If the underlying method is static, then the specified {@code obj}
 539      * argument is ignored. It may be null.
 540      *
 541      * <p>If the number of formal parameters required by the underlying method is


 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     }
 615 
 616     /**
 617      * Returns {@code true} if this method is a bridge
 618      * method; returns {@code false} otherwise.
 619      *
 620      * @return true if and only if this method is a bridge
 621      * method as defined by the Java Language Specification.
 622      * @since 1.5
 623      */
 624     public boolean isBridge() {
 625         return (getModifiers() & Modifier.BRIDGE) != 0;
 626     }
 627 
 628     /**
 629      * Returns {@code true} if this method was declared to take
 630      * a variable number of arguments; returns {@code false}
 631      * otherwise.
 632      *
 633      * @return {@code true} if an only if this method was declared to


 637     public boolean isVarArgs() {
 638         return (getModifiers() & Modifier.VARARGS) != 0;
 639     }
 640 
 641     /**
 642      * Returns {@code true} if this method is a synthetic
 643      * method; returns {@code false} otherwise.
 644      *
 645      * @return true if and only if this method is a synthetic
 646      * method as defined by the Java Language Specification.
 647      * @since 1.5
 648      */
 649     public boolean isSynthetic() {
 650         return Modifier.isSynthetic(getModifiers());
 651     }
 652 
 653     // NOTE that there is no synchronization used here. It is correct
 654     // (though not efficient) to generate more than one MethodAccessor
 655     // for a given Method. However, avoiding synchronization will
 656     // probably make the implementation more scalable.
 657     private void acquireMethodAccessor() {
 658         // First check to see if one has been created yet, and take it
 659         // if so
 660         MethodAccessor tmp = null;
 661         if (root != null) tmp = root.getMethodAccessor();
 662         if (tmp != null) {
 663             methodAccessor = tmp;
 664             return;
 665         }
 666         // Otherwise fabricate one and propagate it up to the root
 667         tmp = reflectionFactory.newMethodAccessor(this);
 668         setMethodAccessor(tmp);
 669     }
 670 



 671     // Returns MethodAccessor for this Method object, not looking up
 672     // the chain to the root
 673     MethodAccessor getMethodAccessor() {
 674         return methodAccessor;
 675     }
 676 
 677     // Sets the MethodAccessor for this Method object and
 678     // (recursively) its root
 679     void setMethodAccessor(MethodAccessor accessor) {
 680         methodAccessor = accessor;
 681         // Propagate up
 682         if (root != null) {
 683             root.setMethodAccessor(accessor);
 684         }
 685     }
 686 
 687     /**
 688      * @throws NullPointerException {@inheritDoc}
 689      * @since 1.5
 690      */




  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    // Generics infrastructure
  87 
  88     private String getGenericSignature() {return signature;}
  89 
  90     // Accessor for factory
  91     private GenericsFactory getFactory() {
  92         // create scope and factory
  93         return CoreReflectionFactory.make(this, MethodScope.make(this));
  94     }
  95 
  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(),
 102                                                 getFactory());
 103         }
 104         return genericInfo; //return cached repository
 105     }


 380      * class declaring the method, followed by a period, followed by
 381      * the method name, followed by a parenthesized, comma-separated
 382      * list of the method's formal parameter types. If the method
 383      * throws checked exceptions, the parameter list is followed by a
 384      * space, followed by the word throws followed by a
 385      * comma-separated list of the thrown exception types.
 386      * For example:
 387      * <pre>
 388      *    public boolean java.lang.Object.equals(java.lang.Object)
 389      * </pre>
 390      *
 391      * <p>The access modifiers are placed in canonical order as
 392      * specified by "The Java Language Specification".  This is
 393      * {@code public}, {@code protected} or {@code private} first,
 394      * and then other modifiers in the following order:
 395      * {@code abstract}, {@code static}, {@code final},
 396      * {@code synchronized}, {@code native}, {@code strictfp}.
 397      */
 398     public String toString() {
 399         try {
 400             StringBuilder sb = new StringBuilder();
 401             int mod = getModifiers() & Modifier.methodModifiers();
 402             if (mod != 0) {
 403                 sb.append(Modifier.toString(mod)).append(' ');
 404             }
 405             sb.append(Field.getTypeName(getReturnType())).append(' ');
 406             sb.append(Field.getTypeName(getDeclaringClass())).append('.');
 407             sb.append(getName()).append('(');
 408             Class<?>[] params = parameterTypes; // avoid clone
 409             for (int j = 0; j < params.length; j++) {
 410                 sb.append(Field.getTypeName(params[j]));
 411                 if (j < (params.length - 1))
 412                     sb.append(',');
 413             }
 414             sb.append(')');
 415             Class<?>[] exceptions = exceptionTypes; // avoid clone
 416             if (exceptions.length > 0) {
 417                 sb.append(" throws ");
 418                 for (int k = 0; k < exceptions.length; k++) {
 419                     sb.append(exceptions[k].getName());
 420                     if (k < (exceptions.length - 1))
 421                         sb.append(',');
 422                 }
 423             }
 424             return sb.toString();
 425         } catch (Exception e) {
 426             return "<" + e + ">";
 427         }
 428     }
 429 
 430     /**
 431      * Returns a string describing this {@code Method}, including
 432      * type parameters.  The string is formatted as the method access
 433      * modifiers, if any, followed by an angle-bracketed
 434      * comma-separated list of the method's type parameters, if any,
 435      * followed by the method's generic return type, followed by a
 436      * space, followed by the class declaring the method, followed by
 437      * a period, followed by the method name, followed by a
 438      * parenthesized, comma-separated list of the method's generic
 439      * formal parameter types.
 440      *
 441      * If this method was declared to take a variable number of


 453      * exception types.  If there are no type parameters, the type
 454      * parameter list is elided.
 455      *
 456      * <p>The access modifiers are placed in canonical order as
 457      * specified by "The Java Language Specification".  This is
 458      * {@code public}, {@code protected} or {@code private} first,
 459      * and then other modifiers in the following order:
 460      * {@code abstract}, {@code static}, {@code final},
 461      * {@code synchronized}, {@code native}, {@code strictfp}.
 462      *
 463      * @return a string describing this {@code Method},
 464      * include type parameters
 465      *
 466      * @since 1.5
 467      */
 468     public String toGenericString() {
 469         try {
 470             StringBuilder sb = new StringBuilder();
 471             int mod = getModifiers() & Modifier.methodModifiers();
 472             if (mod != 0) {
 473                 sb.append(Modifier.toString(mod)).append(' ');
 474             }
 475             TypeVariable<?>[] typeparms = getTypeParameters();
 476             if (typeparms.length > 0) {
 477                 boolean first = true;
 478                 sb.append('<');
 479                 for(TypeVariable<?> typeparm: typeparms) {
 480                     if (!first)
 481                         sb.append(',');
 482                     // Class objects can't occur here; no need to test
 483                     // and call Class.getName().
 484                     sb.append(typeparm.toString());
 485                     first = false;
 486                 }
 487                 sb.append("> ");
 488             }
 489 
 490             Type genRetType = getGenericReturnType();
 491             sb.append( ((genRetType instanceof Class<?>)?
 492                         Field.getTypeName((Class<?>)genRetType):genRetType.toString()))
 493                     .append(' ');
 494 
 495             sb.append(Field.getTypeName(getDeclaringClass())).append('.');
 496             sb.append(getName()).append('(');
 497             Type[] params = getGenericParameterTypes();
 498             for (int j = 0; j < params.length; j++) {
 499                 String param = (params[j] instanceof Class)?
 500                     Field.getTypeName((Class)params[j]):
 501                     (params[j].toString());
 502                 if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
 503                     param = param.replaceFirst("\\[\\]$", "...");
 504                 sb.append(param);
 505                 if (j < (params.length - 1))
 506                     sb.append(',');
 507             }
 508             sb.append(')');
 509             Type[] exceptions = getGenericExceptionTypes();
 510             if (exceptions.length > 0) {
 511                 sb.append(" throws ");
 512                 for (int k = 0; k < exceptions.length; k++) {
 513                     sb.append((exceptions[k] instanceof Class)?
 514                               ((Class)exceptions[k]).getName():
 515                               exceptions[k].toString());
 516                     if (k < (exceptions.length - 1))
 517                         sb.append(',');
 518                 }
 519             }
 520             return sb.toString();
 521         } catch (Exception e) {
 522             return "<" + e + ">";
 523         }
 524     }
 525 
 526     /**
 527      * Invokes the underlying method represented by this {@code Method}
 528      * object, on the specified object with the specified parameters.
 529      * Individual parameters are automatically unwrapped to match
 530      * primitive formal parameters, and both primitive and reference
 531      * parameters are subject to method invocation conversions as
 532      * necessary.
 533      *
 534      * <p>If the underlying method is static, then the specified {@code obj}
 535      * argument is ignored. It may be null.
 536      *
 537      * <p>If the number of formal parameters required by the underlying method is


 570      *              or implementor thereof); if the number of actual
 571      *              and formal parameters differ; if an unwrapping
 572      *              conversion for primitive arguments fails; or if,
 573      *              after possible unwrapping, a parameter value
 574      *              cannot be converted to the corresponding formal
 575      *              parameter type by a method invocation conversion.
 576      * @exception InvocationTargetException if the underlying method
 577      *              throws an exception.
 578      * @exception NullPointerException      if the specified object is null
 579      *              and the method is an instance method.
 580      * @exception ExceptionInInitializerError if the initialization
 581      * provoked by this method fails.
 582      */
 583     public Object invoke(Object obj, Object... args)
 584         throws IllegalAccessException, IllegalArgumentException,
 585            InvocationTargetException
 586     {
 587         if (!override) {
 588             if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
 589                 Class<?> caller = Reflection.getCallerClass(1);



 590 
 591                 checkAccess(caller, clazz, obj, modifiers);










 592             }
 593         }
 594         MethodAccessor ma = methodAccessor;             // read volatile
 595         if (ma == null) {
 596             ma = acquireMethodAccessor();
 597         }
 598         return ma.invoke(obj, args);

 599     }
 600 
 601     /**
 602      * Returns {@code true} if this method is a bridge
 603      * method; returns {@code false} otherwise.
 604      *
 605      * @return true if and only if this method is a bridge
 606      * method as defined by the Java Language Specification.
 607      * @since 1.5
 608      */
 609     public boolean isBridge() {
 610         return (getModifiers() & Modifier.BRIDGE) != 0;
 611     }
 612 
 613     /**
 614      * Returns {@code true} if this method was declared to take
 615      * a variable number of arguments; returns {@code false}
 616      * otherwise.
 617      *
 618      * @return {@code true} if an only if this method was declared to


 622     public boolean isVarArgs() {
 623         return (getModifiers() & Modifier.VARARGS) != 0;
 624     }
 625 
 626     /**
 627      * Returns {@code true} if this method is a synthetic
 628      * method; returns {@code false} otherwise.
 629      *
 630      * @return true if and only if this method is a synthetic
 631      * method as defined by the Java Language Specification.
 632      * @since 1.5
 633      */
 634     public boolean isSynthetic() {
 635         return Modifier.isSynthetic(getModifiers());
 636     }
 637 
 638     // NOTE that there is no synchronization used here. It is correct
 639     // (though not efficient) to generate more than one MethodAccessor
 640     // for a given Method. However, avoiding synchronization will
 641     // probably make the implementation more scalable.
 642     private MethodAccessor acquireMethodAccessor() {
 643         // First check to see if one has been created yet, and take it
 644         // if so
 645         MethodAccessor tmp = null;
 646         if (root != null) tmp = root.getMethodAccessor();
 647         if (tmp != null) {
 648             methodAccessor = tmp;
 649         } else {

 650             // Otherwise fabricate one and propagate it up to the root
 651             tmp = reflectionFactory.newMethodAccessor(this);
 652             setMethodAccessor(tmp);
 653         }
 654 
 655         return tmp;
 656     }
 657 
 658     // Returns MethodAccessor for this Method object, not looking up
 659     // the chain to the root
 660     MethodAccessor getMethodAccessor() {
 661         return methodAccessor;
 662     }
 663 
 664     // Sets the MethodAccessor for this Method object and
 665     // (recursively) its root
 666     void setMethodAccessor(MethodAccessor accessor) {
 667         methodAccessor = accessor;
 668         // Propagate up
 669         if (root != null) {
 670             root.setMethodAccessor(accessor);
 671         }
 672     }
 673 
 674     /**
 675      * @throws NullPointerException {@inheritDoc}
 676      * @since 1.5
 677      */