Save This Page
Home » Open-JDK-6.b17-src » java » lang » reflect » [javadoc | source]
    1   /*
    2    * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   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).
   16    *
   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.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package java.lang.reflect;
   27   
   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;
   39   import java.util.Map;
   40   
   41   /**
   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).
   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       // Modifiers that can be applied to a method in source code
   92       private static final int LANGUAGE_MODIFIERS =
   93           Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
   94           Modifier.ABSTRACT       | Modifier.STATIC       | Modifier.FINAL   |
   95           Modifier.SYNCHRONIZED   | Modifier.NATIVE;
   96   
   97      // Generics infrastructure
   98   
   99       private String getGenericSignature() {return signature;}
  100   
  101       // Accessor for factory
  102       private GenericsFactory getFactory() {
  103           // create scope and factory
  104           return CoreReflectionFactory.make(this, MethodScope.make(this));
  105       }
  106   
  107       // Accessor for generic info repository
  108       private MethodRepository getGenericInfo() {
  109           // lazily initialize repository if necessary
  110           if (genericInfo == null) {
  111               // create and cache generic info repository
  112               genericInfo = MethodRepository.make(getGenericSignature(),
  113                                                   getFactory());
  114           }
  115           return genericInfo; //return cached repository
  116       }
  117   
  118       /**
  119        * Package-private constructor used by ReflectAccess to enable
  120        * instantiation of these objects in Java code from the java.lang
  121        * package via sun.reflect.LangReflectAccess.
  122        */
  123       Method(Class declaringClass,
  124              String name,
  125              Class[] parameterTypes,
  126              Class returnType,
  127              Class[] checkedExceptions,
  128              int modifiers,
  129              int slot,
  130              String signature,
  131              byte[] annotations,
  132              byte[] parameterAnnotations,
  133              byte[] annotationDefault)
  134       {
  135           this.clazz = declaringClass;
  136           this.name = name;
  137           this.parameterTypes = parameterTypes;
  138           this.returnType = returnType;
  139           this.exceptionTypes = checkedExceptions;
  140           this.modifiers = modifiers;
  141           this.slot = slot;
  142           this.signature = signature;
  143           this.annotations = annotations;
  144           this.parameterAnnotations = parameterAnnotations;
  145           this.annotationDefault = annotationDefault;
  146       }
  147   
  148       /**
  149        * Package-private routine (exposed to java.lang.Class via
  150        * ReflectAccess) which returns a copy of this Method. The copy's
  151        * "root" field points to this Method.
  152        */
  153       Method copy() {
  154           // This routine enables sharing of MethodAccessor objects
  155           // among Method objects which refer to the same underlying
  156           // method in the VM. (All of this contortion is only necessary
  157           // because of the "accessibility" bit in AccessibleObject,
  158           // which implicitly requires that new java.lang.reflect
  159           // objects be fabricated for each reflective call on Class
  160           // objects.)
  161           Method res = new Method(clazz, name, parameterTypes, returnType,
  162                                   exceptionTypes, modifiers, slot, signature,
  163                                   annotations, parameterAnnotations, annotationDefault);
  164           res.root = this;
  165           // Might as well eagerly propagate this if already present
  166           res.methodAccessor = methodAccessor;
  167           return res;
  168       }
  169   
  170       /**
  171        * Returns the {@code Class} object representing the class or interface
  172        * that declares the method represented by this {@code Method} object.
  173        */
  174       public Class<?> getDeclaringClass() {
  175           return clazz;
  176       }
  177   
  178       /**
  179        * Returns the name of the method represented by this {@code Method}
  180        * object, as a {@code String}.
  181        */
  182       public String getName() {
  183           return name;
  184       }
  185   
  186       /**
  187        * Returns the Java language modifiers for the method represented
  188        * by this {@code Method} object, as an integer. The {@code Modifier} class should
  189        * be used to decode the modifiers.
  190        *
  191        * @see Modifier
  192        */
  193       public int getModifiers() {
  194           return modifiers;
  195       }
  196   
  197       /**
  198        * Returns an array of {@code TypeVariable} objects that represent the
  199        * type variables declared by the generic declaration represented by this
  200        * {@code GenericDeclaration} object, in declaration order.  Returns an
  201        * array of length 0 if the underlying generic declaration declares no type
  202        * variables.
  203        *
  204        * @return an array of {@code TypeVariable} objects that represent
  205        *     the type variables declared by this generic declaration
  206        * @throws GenericSignatureFormatError if the generic
  207        *     signature of this generic declaration does not conform to
  208        *     the format specified in the Java Virtual Machine Specification,
  209        *     3rd edition
  210        * @since 1.5
  211        */
  212       public TypeVariable<Method>[] getTypeParameters() {
  213           if (getGenericSignature() != null)
  214               return (TypeVariable<Method>[])getGenericInfo().getTypeParameters();
  215           else
  216               return (TypeVariable<Method>[])new TypeVariable[0];
  217       }
  218   
  219       /**
  220        * Returns a {@code Class} object that represents the formal return type
  221        * of the method represented by this {@code Method} object.
  222        *
  223        * @return the return type for the method this object represents
  224        */
  225       public Class<?> getReturnType() {
  226           return returnType;
  227       }
  228   
  229       /**
  230        * Returns a {@code Type} object that represents the formal return
  231        * type of the method represented by this {@code Method} object.
  232        *
  233        * <p>If the return type is a parameterized type,
  234        * the {@code Type} object returned must accurately reflect
  235        * the actual type parameters used in the source code.
  236        *
  237        * <p>If the return type is a type variable or a parameterized type, it
  238        * is created. Otherwise, it is resolved.
  239        *
  240        * @return  a {@code Type} object that represents the formal return
  241        *     type of the underlying  method
  242        * @throws GenericSignatureFormatError
  243        *     if the generic method signature does not conform to the format
  244        *     specified in the Java Virtual Machine Specification, 3rd edition
  245        * @throws TypeNotPresentException if the underlying method's
  246        *     return type refers to a non-existent type declaration
  247        * @throws MalformedParameterizedTypeException if the
  248        *     underlying method's return typed refers to a parameterized
  249        *     type that cannot be instantiated for any reason
  250        * @since 1.5
  251        */
  252       public Type getGenericReturnType() {
  253         if (getGenericSignature() != null) {
  254           return getGenericInfo().getReturnType();
  255         } else { return getReturnType();}
  256       }
  257   
  258   
  259       /**
  260        * Returns an array of {@code Class} objects that represent the formal
  261        * parameter types, in declaration order, of the method
  262        * represented by this {@code Method} object.  Returns an array of length
  263        * 0 if the underlying method takes no parameters.
  264        *
  265        * @return the parameter types for the method this object
  266        * represents
  267        */
  268       public Class<?>[] getParameterTypes() {
  269           return (Class<?>[]) parameterTypes.clone();
  270       }
  271   
  272       /**
  273        * Returns an array of {@code Type} objects that represent the formal
  274        * parameter types, in declaration order, of the method represented by
  275        * this {@code Method} object. Returns an array of length 0 if the
  276        * underlying method takes no parameters.
  277        *
  278        * <p>If a formal parameter type is a parameterized type,
  279        * the {@code Type} object returned for it must accurately reflect
  280        * the actual type parameters used in the source code.
  281        *
  282        * <p>If a formal parameter type is a type variable or a parameterized
  283        * type, it is created. Otherwise, it is resolved.
  284        *
  285        * @return an array of Types that represent the formal
  286        *     parameter types of the underlying method, in declaration order
  287        * @throws GenericSignatureFormatError
  288        *     if the generic method signature does not conform to the format
  289        *     specified in the Java Virtual Machine Specification, 3rd edition
  290        * @throws TypeNotPresentException if any of the parameter
  291        *     types of the underlying method refers to a non-existent type
  292        *     declaration
  293        * @throws MalformedParameterizedTypeException if any of
  294        *     the underlying method's parameter types refer to a parameterized
  295        *     type that cannot be instantiated for any reason
  296        * @since 1.5
  297        */
  298       public Type[] getGenericParameterTypes() {
  299           if (getGenericSignature() != null)
  300               return getGenericInfo().getParameterTypes();
  301           else
  302               return getParameterTypes();
  303       }
  304   
  305   
  306       /**
  307        * Returns an array of {@code Class} objects that represent
  308        * the types of the exceptions declared to be thrown
  309        * by the underlying method
  310        * represented by this {@code Method} object.  Returns an array of length
  311        * 0 if the method declares no exceptions in its {@code throws} clause.
  312        *
  313        * @return the exception types declared as being thrown by the
  314        * method this object represents
  315        */
  316       public Class<?>[] getExceptionTypes() {
  317           return (Class<?>[]) exceptionTypes.clone();
  318       }
  319   
  320       /**
  321        * Returns an array of {@code Type} objects that represent the
  322        * exceptions declared to be thrown by this {@code Method} object.
  323        * Returns an array of length 0 if the underlying method declares
  324        * no exceptions in its {@code throws} clause.
  325        *
  326        * <p>If an exception type is a parameterized type, the {@code Type}
  327        * object returned for it must accurately reflect the actual type
  328        * parameters used in the source code.
  329        *
  330        * <p>If an exception type is a type variable or a parameterized
  331        * type, it is created. Otherwise, it is resolved.
  332        *
  333        * @return an array of Types that represent the exception types
  334        *     thrown by the underlying method
  335        * @throws GenericSignatureFormatError
  336        *     if the generic method signature does not conform to the format
  337        *     specified in the Java Virtual Machine Specification, 3rd edition
  338        * @throws TypeNotPresentException if the underlying method's
  339        *     {@code throws} clause refers to a non-existent type declaration
  340        * @throws MalformedParameterizedTypeException if
  341        *     the underlying method's {@code throws} clause refers to a
  342        *     parameterized type that cannot be instantiated for any reason
  343        * @since 1.5
  344        */
  345         public Type[] getGenericExceptionTypes() {
  346             Type[] result;
  347             if (getGenericSignature() != null &&
  348                 ((result = getGenericInfo().getExceptionTypes()).length > 0))
  349                 return result;
  350             else
  351                 return getExceptionTypes();
  352         }
  353   
  354       /**
  355        * Compares this {@code Method} against the specified object.  Returns
  356        * true if the objects are the same.  Two {@code Methods} are the same if
  357        * they were declared by the same class and have the same name
  358        * and formal parameter types and return type.
  359        */
  360       public boolean equals(Object obj) {
  361           if (obj != null && obj instanceof Method) {
  362               Method other = (Method)obj;
  363               if ((getDeclaringClass() == other.getDeclaringClass())
  364                   && (getName() == other.getName())) {
  365                   if (!returnType.equals(other.getReturnType()))
  366                       return false;
  367                   /* Avoid unnecessary cloning */
  368                   Class[] params1 = parameterTypes;
  369                   Class[] params2 = other.parameterTypes;
  370                   if (params1.length == params2.length) {
  371                       for (int i = 0; i < params1.length; i++) {
  372                           if (params1[i] != params2[i])
  373                               return false;
  374                       }
  375                       return true;
  376                   }
  377               }
  378           }
  379           return false;
  380       }
  381   
  382       /**
  383        * Returns a hashcode for this {@code Method}.  The hashcode is computed
  384        * as the exclusive-or of the hashcodes for the underlying
  385        * method's declaring class name and the method's name.
  386        */
  387       public int hashCode() {
  388           return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
  389       }
  390   
  391       /**
  392        * Returns a string describing this {@code Method}.  The string is
  393        * formatted as the method access modifiers, if any, followed by
  394        * the method return type, followed by a space, followed by the
  395        * class declaring the method, followed by a period, followed by
  396        * the method name, followed by a parenthesized, comma-separated
  397        * list of the method's formal parameter types. If the method
  398        * throws checked exceptions, the parameter list is followed by a
  399        * space, followed by the word throws followed by a
  400        * comma-separated list of the thrown exception types.
  401        * For example:
  402        * <pre>
  403        *    public boolean java.lang.Object.equals(java.lang.Object)
  404        * </pre>
  405        *
  406        * <p>The access modifiers are placed in canonical order as
  407        * specified by "The Java Language Specification".  This is
  408        * {@code public}, {@code protected} or {@code private} first,
  409        * and then other modifiers in the following order:
  410        * {@code abstract}, {@code static}, {@code final},
  411        * {@code synchronized}, {@code native}.
  412        */
  413       public String toString() {
  414           try {
  415               StringBuffer sb = new StringBuffer();
  416               int mod = getModifiers() & LANGUAGE_MODIFIERS;
  417               if (mod != 0) {
  418                   sb.append(Modifier.toString(mod) + " ");
  419               }
  420               sb.append(Field.getTypeName(getReturnType()) + " ");
  421               sb.append(Field.getTypeName(getDeclaringClass()) + ".");
  422               sb.append(getName() + "(");
  423               Class[] params = parameterTypes; // avoid clone
  424               for (int j = 0; j < params.length; j++) {
  425                   sb.append(Field.getTypeName(params[j]));
  426                   if (j < (params.length - 1))
  427                       sb.append(",");
  428               }
  429               sb.append(")");
  430               Class[] exceptions = exceptionTypes; // avoid clone
  431               if (exceptions.length > 0) {
  432                   sb.append(" throws ");
  433                   for (int k = 0; k < exceptions.length; k++) {
  434                       sb.append(exceptions[k].getName());
  435                       if (k < (exceptions.length - 1))
  436                           sb.append(",");
  437                   }
  438               }
  439               return sb.toString();
  440           } catch (Exception e) {
  441               return "<" + e + ">";
  442           }
  443       }
  444   
  445       /**
  446        * Returns a string describing this {@code Method}, including
  447        * type parameters.  The string is formatted as the method access
  448        * modifiers, if any, followed by an angle-bracketed
  449        * comma-separated list of the method's type parameters, if any,
  450        * followed by the method's generic return type, followed by a
  451        * space, followed by the class declaring the method, followed by
  452        * a period, followed by the method name, followed by a
  453        * parenthesized, comma-separated list of the method's generic
  454        * formal parameter types.
  455        *
  456        * A space is used to separate access modifiers from one another
  457        * and from the type parameters or return type.  If there are no
  458        * type parameters, the type parameter list is elided; if the type
  459        * parameter list is present, a space separates the list from the
  460        * class name.  If the method is declared to throw exceptions, the
  461        * parameter list is followed by a space, followed by the word
  462        * throws followed by a comma-separated list of the generic thrown
  463        * exception types.  If there are no type parameters, the type
  464        * parameter list is elided.
  465        *
  466        * <p>The access modifiers are placed in canonical order as
  467        * specified by "The Java Language Specification".  This is
  468        * {@code public}, {@code protected} or {@code private} first,
  469        * and then other modifiers in the following order:
  470        * {@code abstract}, {@code static}, {@code final},
  471        * {@code synchronized} {@code native}.
  472        *
  473        * @return a string describing this {@code Method},
  474        * include type parameters
  475        *
  476        * @since 1.5
  477        */
  478       public String toGenericString() {
  479           try {
  480               StringBuilder sb = new StringBuilder();
  481               int mod = getModifiers() & LANGUAGE_MODIFIERS;
  482               if (mod != 0) {
  483                   sb.append(Modifier.toString(mod) + " ");
  484               }
  485               TypeVariable<?>[] typeparms = getTypeParameters();
  486               if (typeparms.length > 0) {
  487                   boolean first = true;
  488                   sb.append("<");
  489                   for(TypeVariable<?> typeparm: typeparms) {
  490                       if (!first)
  491                           sb.append(",");
  492                       // Class objects can't occur here; no need to test
  493                       // and call Class.getName().
  494                       sb.append(typeparm.toString());
  495                       first = false;
  496                   }
  497                   sb.append("> ");
  498               }
  499   
  500               Type genRetType = getGenericReturnType();
  501               sb.append( ((genRetType instanceof Class<?>)?
  502                           Field.getTypeName((Class<?>)genRetType):genRetType.toString())  + " ");
  503   
  504               sb.append(Field.getTypeName(getDeclaringClass()) + ".");
  505               sb.append(getName() + "(");
  506               Type[] params = getGenericParameterTypes();
  507               for (int j = 0; j < params.length; j++) {
  508                   String param = (params[j] instanceof Class)?
  509                       Field.getTypeName((Class)params[j]):
  510                       (params[j].toString());
  511                   sb.append(param);
  512                   if (j < (params.length - 1))
  513                       sb.append(",");
  514               }
  515               sb.append(")");
  516               Type[] exceptions = getGenericExceptionTypes();
  517               if (exceptions.length > 0) {
  518                   sb.append(" throws ");
  519                   for (int k = 0; k < exceptions.length; k++) {
  520                       sb.append((exceptions[k] instanceof Class)?
  521                                 ((Class)exceptions[k]).getName():
  522                                 exceptions[k].toString());
  523                       if (k < (exceptions.length - 1))
  524                           sb.append(",");
  525                   }
  526               }
  527               return sb.toString();
  528           } catch (Exception e) {
  529               return "<" + e + ">";
  530           }
  531       }
  532   
  533       /**
  534        * Invokes the underlying method represented by this {@code Method}
  535        * object, on the specified object with the specified parameters.
  536        * Individual parameters are automatically unwrapped to match
  537        * primitive formal parameters, and both primitive and reference
  538        * parameters are subject to method invocation conversions as
  539        * necessary.
  540        *
  541        * <p>If the underlying method is static, then the specified {@code obj}
  542        * argument is ignored. It may be null.
  543        *
  544        * <p>If the number of formal parameters required by the underlying method is
  545        * 0, the supplied {@code args} array may be of length 0 or null.
  546        *
  547        * <p>If the underlying method is an instance method, it is invoked
  548        * using dynamic method lookup as documented in The Java Language
  549        * Specification, Second Edition, section 15.12.4.4; in particular,
  550        * overriding based on the runtime type of the target object will occur.
  551        *
  552        * <p>If the underlying method is static, the class that declared
  553        * the method is initialized if it has not already been initialized.
  554        *
  555        * <p>If the method completes normally, the value it returns is
  556        * returned to the caller of invoke; if the value has a primitive
  557        * type, it is first appropriately wrapped in an object. However,
  558        * if the value has the type of an array of a primitive type, the
  559        * elements of the array are <i>not</i> wrapped in objects; in
  560        * other words, an array of primitive type is returned.  If the
  561        * underlying method return type is void, the invocation returns
  562        * null.
  563        *
  564        * @param obj  the object the underlying method is invoked from
  565        * @param args the arguments used for the method call
  566        * @return the result of dispatching the method represented by
  567        * this object on {@code obj} with parameters
  568        * {@code args}
  569        *
  570        * @exception IllegalAccessException    if this {@code Method} object
  571        *              enforces Java language access control and the underlying
  572        *              method is inaccessible.
  573        * @exception IllegalArgumentException  if the method is an
  574        *              instance method and the specified object argument
  575        *              is not an instance of the class or interface
  576        *              declaring the underlying method (or of a subclass
  577        *              or implementor thereof); if the number of actual
  578        *              and formal parameters differ; if an unwrapping
  579        *              conversion for primitive arguments fails; or if,
  580        *              after possible unwrapping, a parameter value
  581        *              cannot be converted to the corresponding formal
  582        *              parameter type by a method invocation conversion.
  583        * @exception InvocationTargetException if the underlying method
  584        *              throws an exception.
  585        * @exception NullPointerException      if the specified object is null
  586        *              and the method is an instance method.
  587        * @exception ExceptionInInitializerError if the initialization
  588        * provoked by this method fails.
  589        */
  590       public Object invoke(Object obj, Object... args)
  591           throws IllegalAccessException, IllegalArgumentException,
  592              InvocationTargetException
  593       {
  594           if (!override) {
  595               if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
  596                   Class caller = Reflection.getCallerClass(1);
  597                   Class targetClass = ((obj == null || !Modifier.isProtected(modifiers))
  598                                        ? clazz
  599                                        : obj.getClass());
  600   
  601                   boolean cached;
  602                   synchronized (this) {
  603                       cached = (securityCheckCache == caller)
  604                               && (securityCheckTargetClassCache == targetClass);
  605                   }
  606                   if (!cached) {
  607                       Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
  608                       synchronized (this) {
  609                           securityCheckCache = caller;
  610                           securityCheckTargetClassCache = targetClass;
  611                       }
  612                   }
  613               }
  614           }
  615           if (methodAccessor == null) acquireMethodAccessor();
  616           return methodAccessor.invoke(obj, args);
  617       }
  618   
  619       /**
  620        * Returns {@code true} if this method is a bridge
  621        * method; returns {@code false} otherwise.
  622        *
  623        * @return true if and only if this method is a bridge
  624        * method as defined by the Java Language Specification.
  625        * @since 1.5
  626        */
  627       public boolean isBridge() {
  628           return (getModifiers() & Modifier.BRIDGE) != 0;
  629       }
  630   
  631       /**
  632        * Returns {@code true} if this method was declared to take
  633        * a variable number of arguments; returns {@code false}
  634        * otherwise.
  635        *
  636        * @return {@code true} if an only if this method was declared to
  637        * take a variable number of arguments.
  638        * @since 1.5
  639        */
  640       public boolean isVarArgs() {
  641           return (getModifiers() & Modifier.VARARGS) != 0;
  642       }
  643   
  644       /**
  645        * Returns {@code true} if this method is a synthetic
  646        * method; returns {@code false} otherwise.
  647        *
  648        * @return true if and only if this method is a synthetic
  649        * method as defined by the Java Language Specification.
  650        * @since 1.5
  651        */
  652       public boolean isSynthetic() {
  653           return Modifier.isSynthetic(getModifiers());
  654       }
  655   
  656       // NOTE that there is no synchronization used here. It is correct
  657       // (though not efficient) to generate more than one MethodAccessor
  658       // for a given Method. However, avoiding synchronization will
  659       // probably make the implementation more scalable.
  660       private void acquireMethodAccessor() {
  661           // First check to see if one has been created yet, and take it
  662           // if so
  663           MethodAccessor tmp = null;
  664           if (root != null) tmp = root.getMethodAccessor();
  665           if (tmp != null) {
  666               methodAccessor = tmp;
  667               return;
  668           }
  669           // Otherwise fabricate one and propagate it up to the root
  670           tmp = reflectionFactory.newMethodAccessor(this);
  671           setMethodAccessor(tmp);
  672       }
  673   
  674       // Returns MethodAccessor for this Method object, not looking up
  675       // the chain to the root
  676       MethodAccessor getMethodAccessor() {
  677           return methodAccessor;
  678       }
  679   
  680       // Sets the MethodAccessor for this Method object and
  681       // (recursively) its root
  682       void setMethodAccessor(MethodAccessor accessor) {
  683           methodAccessor = accessor;
  684           // Propagate up
  685           if (root != null) {
  686               root.setMethodAccessor(accessor);
  687           }
  688       }
  689   
  690       /**
  691        * @throws NullPointerException {@inheritDoc}
  692        * @since 1.5
  693        */
  694       public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
  695           if (annotationClass == null)
  696               throw new NullPointerException();
  697   
  698           return (T) declaredAnnotations().get(annotationClass);
  699       }
  700   
  701       private static final Annotation[] EMPTY_ANNOTATION_ARRAY=new Annotation[0];
  702   
  703       /**
  704        * @since 1.5
  705        */
  706       public Annotation[] getDeclaredAnnotations()  {
  707           return declaredAnnotations().values().toArray(EMPTY_ANNOTATION_ARRAY);
  708       }
  709   
  710       private transient Map<Class, Annotation> declaredAnnotations;
  711   
  712       private synchronized  Map<Class, Annotation> declaredAnnotations() {
  713           if (declaredAnnotations == null) {
  714               declaredAnnotations = AnnotationParser.parseAnnotations(
  715                   annotations, sun.misc.SharedSecrets.getJavaLangAccess().
  716                   getConstantPool(getDeclaringClass()),
  717                   getDeclaringClass());
  718           }
  719           return declaredAnnotations;
  720       }
  721   
  722       /**
  723        * Returns the default value for the annotation member represented by
  724        * this {@code Method} instance.  If the member is of a primitive type,
  725        * an instance of the corresponding wrapper type is returned. Returns
  726        * null if no default is associated with the member, or if the method
  727        * instance does not represent a declared member of an annotation type.
  728        *
  729        * @return the default value for the annotation member represented
  730        *     by this {@code Method} instance.
  731        * @throws TypeNotPresentException if the annotation is of type
  732        *     {@link Class} and no definition can be found for the
  733        *     default class value.
  734        * @since  1.5
  735        */
  736       public Object getDefaultValue() {
  737           if  (annotationDefault == null)
  738               return null;
  739           Class memberType = AnnotationType.invocationHandlerReturnType(
  740               getReturnType());
  741           Object result = AnnotationParser.parseMemberValue(
  742               memberType, ByteBuffer.wrap(annotationDefault),
  743               sun.misc.SharedSecrets.getJavaLangAccess().
  744                   getConstantPool(getDeclaringClass()),
  745               getDeclaringClass());
  746           if (result instanceof sun.reflect.annotation.ExceptionProxy)
  747               throw new AnnotationFormatError("Invalid default: " + this);
  748           return result;
  749       }
  750   
  751       /**
  752        * Returns an array of arrays that represent the annotations on the formal
  753        * parameters, in declaration order, of the method represented by
  754        * this {@code Method} object. (Returns an array of length zero if the
  755        * underlying method is parameterless.  If the method has one or more
  756        * parameters, a nested array of length zero is returned for each parameter
  757        * with no annotations.) The annotation objects contained in the returned
  758        * arrays are serializable.  The caller of this method is free to modify
  759        * the returned arrays; it will have no effect on the arrays returned to
  760        * other callers.
  761        *
  762        * @return an array of arrays that represent the annotations on the formal
  763        *    parameters, in declaration order, of the method represented by this
  764        *    Method object
  765        * @since 1.5
  766        */
  767       public Annotation[][] getParameterAnnotations() {
  768           int numParameters = parameterTypes.length;
  769           if (parameterAnnotations == null)
  770               return new Annotation[numParameters][0];
  771   
  772           Annotation[][] result = AnnotationParser.parseParameterAnnotations(
  773               parameterAnnotations,
  774               sun.misc.SharedSecrets.getJavaLangAccess().
  775                   getConstantPool(getDeclaringClass()),
  776               getDeclaringClass());
  777           if (result.length != numParameters)
  778               throw new java.lang.annotation.AnnotationFormatError(
  779                   "Parameter annotations don't match number of parameters");
  780           return result;
  781       }
  782   }

Save This Page
Home » Open-JDK-6.b17-src » java » lang » reflect » [javadoc | source]