Save This Page
Home » openjdk-7 » java » lang » reflect » [javadoc | source]
    1   /*
    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.
    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.  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.
   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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * 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      // 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       }
  106   
  107       /**
  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.
  111        */
  112       Method(Class<?> declaringClass,
  113              String name,
  114              Class<?>[] parameterTypes,
  115              Class<?> returnType,
  116              Class<?>[] checkedExceptions,
  117              int modifiers,
  118              int slot,
  119              String signature,
  120              byte[] annotations,
  121              byte[] parameterAnnotations,
  122              byte[] annotationDefault)
  123       {
  124           this.clazz = declaringClass;
  125           this.name = name;
  126           this.parameterTypes = parameterTypes;
  127           this.returnType = returnType;
  128           this.exceptionTypes = checkedExceptions;
  129           this.modifiers = modifiers;
  130           this.slot = slot;
  131           this.signature = signature;
  132           this.annotations = annotations;
  133           this.parameterAnnotations = parameterAnnotations;
  134           this.annotationDefault = annotationDefault;
  135       }
  136   
  137       /**
  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.
  141        */
  142       Method copy() {
  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
  149           // objects.)
  150           Method res = new Method(clazz, name, parameterTypes, returnType,
  151                                   exceptionTypes, modifiers, slot, signature,
  152                                   annotations, parameterAnnotations, annotationDefault);
  153           res.root = this;
  154           // Might as well eagerly propagate this if already present
  155           res.methodAccessor = methodAccessor;
  156           return res;
  157       }
  158   
  159       /**
  160        * Returns the {@code Class} object representing the class or interface
  161        * that declares the method represented by this {@code Method} object.
  162        */
  163       public Class<?> getDeclaringClass() {
  164           return clazz;
  165       }
  166   
  167       /**
  168        * Returns the name of the method represented by this {@code Method}
  169        * object, as a {@code String}.
  170        */
  171       public String getName() {
  172           return name;
  173       }
  174   
  175       /**
  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.
  179        *
  180        * @see Modifier
  181        */
  182       public int getModifiers() {
  183           return modifiers;
  184       }
  185   
  186       /**
  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
  191        * variables.
  192        *
  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&trade; Virtual Machine Specification</cite>
  199        * @since 1.5
  200        */
  201       public TypeVariable<Method>[] getTypeParameters() {
  202           if (getGenericSignature() != null)
  203               return (TypeVariable<Method>[])getGenericInfo().getTypeParameters();
  204           else
  205               return (TypeVariable<Method>[])new TypeVariable[0];
  206       }
  207   
  208       /**
  209        * Returns a {@code Class} object that represents the formal return type
  210        * of the method represented by this {@code Method} object.
  211        *
  212        * @return the return type for the method this object represents
  213        */
  214       public Class<?> getReturnType() {
  215           return returnType;
  216       }
  217   
  218       /**
  219        * Returns a {@code Type} object that represents the formal return
  220        * type of the method represented by this {@code Method} object.
  221        *
  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.
  225        *
  226        * <p>If the return type is a type variable or a parameterized type, it
  227        * is created. Otherwise, it is resolved.
  228        *
  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
  233        *     specified in
  234        *     <cite>The Java&trade; 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
  240        * @since 1.5
  241        */
  242       public Type getGenericReturnType() {
  243         if (getGenericSignature() != null) {
  244           return getGenericInfo().getReturnType();
  245         } else { return getReturnType();}
  246       }
  247   
  248   
  249       /**
  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.
  254        *
  255        * @return the parameter types for the method this object
  256        * represents
  257        */
  258       public Class<?>[] getParameterTypes() {
  259           return (Class<?>[]) parameterTypes.clone();
  260       }
  261   
  262       /**
  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.
  267        *
  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.
  271        *
  272        * <p>If a formal parameter type is a type variable or a parameterized
  273        * type, it is created. Otherwise, it is resolved.
  274        *
  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
  279        *     specified in
  280        *     <cite>The Java&trade; Virtual Machine Specification</cite>
  281        * @throws TypeNotPresentException if any of the parameter
  282        *     types of the underlying method refers to a non-existent type
  283        *     declaration
  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
  287        * @since 1.5
  288        */
  289       public Type[] getGenericParameterTypes() {
  290           if (getGenericSignature() != null)
  291               return getGenericInfo().getParameterTypes();
  292           else
  293               return getParameterTypes();
  294       }
  295   
  296   
  297       /**
  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.
  303        *
  304        * @return the exception types declared as being thrown by the
  305        * method this object represents
  306        */
  307       public Class<?>[] getExceptionTypes() {
  308           return (Class<?>[]) exceptionTypes.clone();
  309       }
  310   
  311       /**
  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.
  316        *
  317        * <p>If an exception type is a type variable or a parameterized
  318        * type, it is created. Otherwise, it is resolved.
  319        *
  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
  324        *     specified in
  325        *     <cite>The Java&trade; 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
  331        * @since 1.5
  332        */
  333         public Type[] getGenericExceptionTypes() {
  334             Type[] result;
  335             if (getGenericSignature() != null &&
  336                 ((result = getGenericInfo().getExceptionTypes()).length > 0))
  337                 return result;
  338             else
  339                 return getExceptionTypes();
  340         }
  341   
  342       /**
  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.
  347        */
  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()))
  354                       return false;
  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])
  361                               return false;
  362                       }
  363                       return true;
  364                   }
  365               }
  366           }
  367           return false;
  368       }
  369   
  370       /**
  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.
  374        */
  375       public int hashCode() {
  376           return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
  377       }
  378   
  379       /**
  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.
  389        * For example:
  390        * <pre>
  391        *    public boolean java.lang.Object.equals(java.lang.Object)
  392        * </pre>
  393        *
  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}.
  400        */
  401       public String toString() {
  402           try {
  403               StringBuilder sb = new StringBuilder();
  404               int mod = getModifiers() & Modifier.methodModifiers();
  405               if (mod != 0) {
  406                   sb.append(Modifier.toString(mod)).append(' ');
  407               }
  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))
  415                       sb.append(',');
  416               }
  417               sb.append(')');
  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))
  424                           sb.append(',');
  425                   }
  426               }
  427               return sb.toString();
  428           } catch (Exception e) {
  429               return "<" + e + ">";
  430           }
  431       }
  432   
  433       /**
  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.
  443        *
  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>".
  448        *
  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.
  458        *
  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}.
  465        *
  466        * @return a string describing this {@code Method},
  467        * include type parameters
  468        *
  469        * @since 1.5
  470        */
  471       public String toGenericString() {
  472           try {
  473               StringBuilder sb = new StringBuilder();
  474               int mod = getModifiers() & Modifier.methodModifiers();
  475               if (mod != 0) {
  476                   sb.append(Modifier.toString(mod)).append(' ');
  477               }
  478               TypeVariable<?>[] typeparms = getTypeParameters();
  479               if (typeparms.length > 0) {
  480                   boolean first = true;
  481                   sb.append('<');
  482                   for(TypeVariable<?> typeparm: typeparms) {
  483                       if (!first)
  484                           sb.append(',');
  485                       // Class objects can't occur here; no need to test
  486                       // and call Class.getName().
  487                       sb.append(typeparm.toString());
  488                       first = false;
  489                   }
  490                   sb.append("> ");
  491               }
  492   
  493               Type genRetType = getGenericReturnType();
  494               sb.append( ((genRetType instanceof Class<?>)?
  495                           Field.getTypeName((Class<?>)genRetType):genRetType.toString()))
  496                       .append(' ');
  497   
  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("\\[\\]$", "...");
  507                   sb.append(param);
  508                   if (j < (params.length - 1))
  509                       sb.append(',');
  510               }
  511               sb.append(')');
  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))
  520                           sb.append(',');
  521                   }
  522               }
  523               return sb.toString();
  524           } catch (Exception e) {
  525               return "<" + e + ">";
  526           }
  527       }
  528   
  529       /**
  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
  535        * necessary.
  536        *
  537        * <p>If the underlying method is static, then the specified {@code obj}
  538        * argument is ignored. It may be null.
  539        *
  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.
  542        *
  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.
  547        *
  548        * <p>If the underlying method is static, the class that declared
  549        * the method is initialized if it has not already been initialized.
  550        *
  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
  558        * null.
  559        *
  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
  564        * {@code args}
  565        *
  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.
  585        */
  586       public Object invoke(Object obj, Object... args)
  587           throws IllegalAccessException, IllegalArgumentException,
  588              InvocationTargetException
  589       {
  590           if (!override) {
  591               if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
  592                   Class<?> caller = Reflection.getCallerClass(1);
  593   
  594                   checkAccess(caller, clazz, obj, modifiers);
  595               }
  596           }
  597           MethodAccessor ma = methodAccessor;             // read volatile
  598           if (ma == null) {
  599               ma = acquireMethodAccessor();
  600           }
  601           return ma.invoke(obj, args);
  602       }
  603   
  604       /**
  605        * Returns {@code true} if this method is a bridge
  606        * method; returns {@code false} otherwise.
  607        *
  608        * @return true if and only if this method is a bridge
  609        * method as defined by the Java Language Specification.
  610        * @since 1.5
  611        */
  612       public boolean isBridge() {
  613           return (getModifiers() & Modifier.BRIDGE) != 0;
  614       }
  615   
  616       /**
  617        * Returns {@code true} if this method was declared to take
  618        * a variable number of arguments; returns {@code false}
  619        * otherwise.
  620        *
  621        * @return {@code true} if an only if this method was declared to
  622        * take a variable number of arguments.
  623        * @since 1.5
  624        */
  625       public boolean isVarArgs() {
  626           return (getModifiers() & Modifier.VARARGS) != 0;
  627       }
  628   
  629       /**
  630        * Returns {@code true} if this method is a synthetic
  631        * method; returns {@code false} otherwise.
  632        *
  633        * @return true if and only if this method is a synthetic
  634        * method as defined by the Java Language Specification.
  635        * @since 1.5
  636        */
  637       public boolean isSynthetic() {
  638           return Modifier.isSynthetic(getModifiers());
  639       }
  640   
  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
  647           // if so
  648           MethodAccessor tmp = null;
  649           if (root != null) tmp = root.getMethodAccessor();
  650           if (tmp != null) {
  651               methodAccessor = tmp;
  652           } else {
  653               // Otherwise fabricate one and propagate it up to the root
  654               tmp = reflectionFactory.newMethodAccessor(this);
  655               setMethodAccessor(tmp);
  656           }
  657   
  658           return tmp;
  659       }
  660   
  661       // Returns MethodAccessor for this Method object, not looking up
  662       // the chain to the root
  663       MethodAccessor getMethodAccessor() {
  664           return methodAccessor;
  665       }
  666   
  667       // Sets the MethodAccessor for this Method object and
  668       // (recursively) its root
  669       void setMethodAccessor(MethodAccessor accessor) {
  670           methodAccessor = accessor;
  671           // Propagate up
  672           if (root != null) {
  673               root.setMethodAccessor(accessor);
  674           }
  675       }
  676   
  677       /**
  678        * @throws NullPointerException {@inheritDoc}
  679        * @since 1.5
  680        */
  681       public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
  682           if (annotationClass == null)
  683               throw new NullPointerException();
  684   
  685           return (T) declaredAnnotations().get(annotationClass);
  686       }
  687   
  688       /**
  689        * @since 1.5
  690        */
  691       public Annotation[] getDeclaredAnnotations()  {
  692           return AnnotationParser.toArray(declaredAnnotations());
  693       }
  694   
  695       private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
  696   
  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());
  703           }
  704           return declaredAnnotations;
  705       }
  706   
  707       /**
  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.
  713        *
  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.
  719        * @since  1.5
  720        */
  721       public Object getDefaultValue() {
  722           if  (annotationDefault == null)
  723               return null;
  724           Class<?> memberType = AnnotationType.invocationHandlerReturnType(
  725               getReturnType());
  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);
  733           return result;
  734       }
  735   
  736       /**
  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
  745        * other callers.
  746        *
  747        * @return an array of arrays that represent the annotations on the formal
  748        *    parameters, in declaration order, of the method represented by this
  749        *    Method object
  750        * @since 1.5
  751        */
  752       public Annotation[][] getParameterAnnotations() {
  753           int numParameters = parameterTypes.length;
  754           if (parameterAnnotations == null)
  755               return new Annotation[numParameters][0];
  756   
  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");
  765           return result;
  766       }
  767   }

Save This Page
Home » openjdk-7 » java » lang » reflect » [javadoc | source]