001 /*
002 * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package java.lang.reflect;
027
028 import sun.reflect.MethodAccessor;
029 import sun.reflect.Reflection;
030 import sun.reflect.generics.repository.MethodRepository;
031 import sun.reflect.generics.factory.CoreReflectionFactory;
032 import sun.reflect.generics.factory.GenericsFactory;
033 import sun.reflect.generics.scope.MethodScope;
034 import sun.reflect.annotation.AnnotationType;
035 import sun.reflect.annotation.AnnotationParser;
036 import java.lang.annotation.Annotation;
037 import java.lang.annotation.AnnotationFormatError;
038 import java.nio.ByteBuffer;
039 import java.util.Map;
040
041 /**
042 * A {@code Method} provides information about, and access to, a single method
043 * on a class or interface. The reflected method may be a class method
044 * or an instance method (including an abstract method).
045 *
046 * <p>A {@code Method} permits widening conversions to occur when matching the
047 * actual parameters to invoke with the underlying method's formal
048 * parameters, but it throws an {@code IllegalArgumentException} if a
049 * narrowing conversion would occur.
050 *
051 * @see Member
052 * @see java.lang.Class
053 * @see java.lang.Class#getMethods()
054 * @see java.lang.Class#getMethod(String, Class[])
055 * @see java.lang.Class#getDeclaredMethods()
056 * @see java.lang.Class#getDeclaredMethod(String, Class[])
057 *
058 * @author Kenneth Russell
059 * @author Nakul Saraiya
060 */
061 public final class Method extends AccessibleObject implements
062 GenericDeclaration, Member {
063 private Class clazz;
064 private int slot;
065 // This is guaranteed to be interned by the VM in the 1.4
066 // reflection implementation
067 private String name;
068 private Class returnType;
069 private Class[] parameterTypes;
070 private Class[] exceptionTypes;
071 private int modifiers;
072 // Generics and annotations support
073 private transient String signature;
074 // generic info repository; lazily initialized
075 private transient MethodRepository genericInfo;
076 private byte[] annotations;
077 private byte[] parameterAnnotations;
078 private byte[] annotationDefault;
079 private volatile MethodAccessor methodAccessor;
080 // For sharing of MethodAccessors. This branching structure is
081 // currently only two levels deep (i.e., one root Method and
082 // potentially many Method objects pointing to it.)
083 private Method root;
084
085 // More complicated security check cache needed here than for
086 // Class.newInstance() and Constructor.newInstance()
087 private Class securityCheckCache;
088 private Class securityCheckTargetClassCache;
089
090 // Modifiers that can be applied to a method in source code
091 private static final int LANGUAGE_MODIFIERS = Modifier.PUBLIC
092 | Modifier.PROTECTED | Modifier.PRIVATE | Modifier.ABSTRACT
093 | Modifier.STATIC | Modifier.FINAL | Modifier.SYNCHRONIZED
094 | Modifier.NATIVE;
095
096 // Generics infrastructure
097
098 private String getGenericSignature() {
099 return signature;
100 }
101
102 // Accessor for factory
103 private GenericsFactory getFactory() {
104 // create scope and factory
105 return CoreReflectionFactory.make(this , MethodScope.make(this ));
106 }
107
108 // Accessor for generic info repository
109 private MethodRepository getGenericInfo() {
110 // lazily initialize repository if necessary
111 if (genericInfo == null) {
112 // create and cache generic info repository
113 genericInfo = MethodRepository.make(getGenericSignature(),
114 getFactory());
115 }
116 return genericInfo; //return cached repository
117 }
118
119 /**
120 * Package-private constructor used by ReflectAccess to enable
121 * instantiation of these objects in Java code from the java.lang
122 * package via sun.reflect.LangReflectAccess.
123 */
124 Method(Class declaringClass, String name, Class[] parameterTypes,
125 Class returnType, Class[] checkedExceptions, int modifiers,
126 int slot, String signature, byte[] annotations,
127 byte[] parameterAnnotations, byte[] annotationDefault) {
128 this .clazz = declaringClass;
129 this .name = name;
130 this .parameterTypes = parameterTypes;
131 this .returnType = returnType;
132 this .exceptionTypes = checkedExceptions;
133 this .modifiers = modifiers;
134 this .slot = slot;
135 this .signature = signature;
136 this .annotations = annotations;
137 this .parameterAnnotations = parameterAnnotations;
138 this .annotationDefault = annotationDefault;
139 }
140
141 /**
142 * Package-private routine (exposed to java.lang.Class via
143 * ReflectAccess) which returns a copy of this Method. The copy's
144 * "root" field points to this Method.
145 */
146 Method copy() {
147 // This routine enables sharing of MethodAccessor objects
148 // among Method objects which refer to the same underlying
149 // method in the VM. (All of this contortion is only necessary
150 // because of the "accessibility" bit in AccessibleObject,
151 // which implicitly requires that new java.lang.reflect
152 // objects be fabricated for each reflective call on Class
153 // objects.)
154 Method res = new Method(clazz, name, parameterTypes,
155 returnType, exceptionTypes, modifiers, slot, signature,
156 annotations, parameterAnnotations, annotationDefault);
157 res.root = this ;
158 // Might as well eagerly propagate this if already present
159 res.methodAccessor = methodAccessor;
160 return res;
161 }
162
163 /**
164 * Returns the {@code Class} object representing the class or interface
165 * that declares the method represented by this {@code Method} object.
166 */
167 public Class<?> getDeclaringClass() {
168 return clazz;
169 }
170
171 /**
172 * Returns the name of the method represented by this {@code Method}
173 * object, as a {@code String}.
174 */
175 public String getName() {
176 return name;
177 }
178
179 /**
180 * Returns the Java language modifiers for the method represented
181 * by this {@code Method} object, as an integer. The {@code Modifier} class should
182 * be used to decode the modifiers.
183 *
184 * @see Modifier
185 */
186 public int getModifiers() {
187 return modifiers;
188 }
189
190 /**
191 * Returns an array of {@code TypeVariable} objects that represent the
192 * type variables declared by the generic declaration represented by this
193 * {@code GenericDeclaration} object, in declaration order. Returns an
194 * array of length 0 if the underlying generic declaration declares no type
195 * variables.
196 *
197 * @return an array of {@code TypeVariable} objects that represent
198 * the type variables declared by this generic declaration
199 * @throws GenericSignatureFormatError if the generic
200 * signature of this generic declaration does not conform to
201 * the format specified in the Java Virtual Machine Specification,
202 * 3rd edition
203 * @since 1.5
204 */
205 public TypeVariable<Method>[] getTypeParameters() {
206 if (getGenericSignature() != null)
207 return (TypeVariable<Method>[]) getGenericInfo()
208 .getTypeParameters();
209 else
210 return (TypeVariable<Method>[]) new TypeVariable[0];
211 }
212
213 /**
214 * Returns a {@code Class} object that represents the formal return type
215 * of the method represented by this {@code Method} object.
216 *
217 * @return the return type for the method this object represents
218 */
219 public Class<?> getReturnType() {
220 return returnType;
221 }
222
223 /**
224 * Returns a {@code Type} object that represents the formal return
225 * type of the method represented by this {@code Method} object.
226 *
227 * <p>If the return type is a parameterized type,
228 * the {@code Type} object returned must accurately reflect
229 * the actual type parameters used in the source code.
230 *
231 * <p>If the return type is a type variable or a parameterized type, it
232 * is created. Otherwise, it is resolved.
233 *
234 * @return a {@code Type} object that represents the formal return
235 * type of the underlying method
236 * @throws GenericSignatureFormatError
237 * if the generic method signature does not conform to the format
238 * specified in the Java Virtual Machine Specification, 3rd edition
239 * @throws TypeNotPresentException if the underlying method's
240 * return type refers to a non-existent type declaration
241 * @throws MalformedParameterizedTypeException if the
242 * underlying method's return typed refers to a parameterized
243 * type that cannot be instantiated for any reason
244 * @since 1.5
245 */
246 public Type getGenericReturnType() {
247 if (getGenericSignature() != null) {
248 return getGenericInfo().getReturnType();
249 } else {
250 return getReturnType();
251 }
252 }
253
254 /**
255 * Returns an array of {@code Class} objects that represent the formal
256 * parameter types, in declaration order, of the method
257 * represented by this {@code Method} object. Returns an array of length
258 * 0 if the underlying method takes no parameters.
259 *
260 * @return the parameter types for the method this object
261 * represents
262 */
263 public Class<?>[] getParameterTypes() {
264 return (Class<?>[]) parameterTypes.clone();
265 }
266
267 /**
268 * Returns an array of {@code Type} objects that represent the formal
269 * parameter types, in declaration order, of the method represented by
270 * this {@code Method} object. Returns an array of length 0 if the
271 * underlying method takes no parameters.
272 *
273 * <p>If a formal parameter type is a parameterized type,
274 * the {@code Type} object returned for it must accurately reflect
275 * the actual type parameters used in the source code.
276 *
277 * <p>If a formal parameter type is a type variable or a parameterized
278 * type, it is created. Otherwise, it is resolved.
279 *
280 * @return an array of Types that represent the formal
281 * parameter types of the underlying method, in declaration order
282 * @throws GenericSignatureFormatError
283 * if the generic method signature does not conform to the format
284 * specified in the Java Virtual Machine Specification, 3rd edition
285 * @throws TypeNotPresentException if any of the parameter
286 * types of the underlying method refers to a non-existent type
287 * declaration
288 * @throws MalformedParameterizedTypeException if any of
289 * the underlying method's parameter types refer to a parameterized
290 * type that cannot be instantiated for any reason
291 * @since 1.5
292 */
293 public Type[] getGenericParameterTypes() {
294 if (getGenericSignature() != null)
295 return getGenericInfo().getParameterTypes();
296 else
297 return getParameterTypes();
298 }
299
300 /**
301 * Returns an array of {@code Class} objects that represent
302 * the types of the exceptions declared to be thrown
303 * by the underlying method
304 * represented by this {@code Method} object. Returns an array of length
305 * 0 if the method declares no exceptions in its {@code throws} clause.
306 *
307 * @return the exception types declared as being thrown by the
308 * method this object represents
309 */
310 public Class<?>[] getExceptionTypes() {
311 return (Class<?>[]) exceptionTypes.clone();
312 }
313
314 /**
315 * Returns an array of {@code Type} objects that represent the
316 * exceptions declared to be thrown by this {@code Method} object.
317 * Returns an array of length 0 if the underlying method declares
318 * no exceptions in its {@code throws} clause.
319 *
320 * <p>If an exception type is a parameterized type, the {@code Type}
321 * object returned for it must accurately reflect the actual type
322 * parameters used in the source code.
323 *
324 * <p>If an exception type is a type variable or a parameterized
325 * type, it is created. Otherwise, it is resolved.
326 *
327 * @return an array of Types that represent the exception types
328 * thrown by the underlying method
329 * @throws GenericSignatureFormatError
330 * if the generic method signature does not conform to the format
331 * specified in the Java Virtual Machine Specification, 3rd edition
332 * @throws TypeNotPresentException if the underlying method's
333 * {@code throws} clause refers to a non-existent type declaration
334 * @throws MalformedParameterizedTypeException if
335 * the underlying method's {@code throws} clause refers to a
336 * parameterized type that cannot be instantiated for any reason
337 * @since 1.5
338 */
339 public Type[] getGenericExceptionTypes() {
340 Type[] result;
341 if (getGenericSignature() != null
342 && ((result = getGenericInfo().getExceptionTypes()).length > 0))
343 return result;
344 else
345 return getExceptionTypes();
346 }
347
348 /**
349 * Compares this {@code Method} against the specified object. Returns
350 * true if the objects are the same. Two {@code Methods} are the same if
351 * they were declared by the same class and have the same name
352 * and formal parameter types and return type.
353 */
354 public boolean equals(Object obj) {
355 if (obj != null && obj instanceof Method) {
356 Method other = (Method) obj;
357 if ((getDeclaringClass() == other.getDeclaringClass())
358 && (getName() == other.getName())) {
359 if (!returnType.equals(other.getReturnType()))
360 return false;
361 /* Avoid unnecessary cloning */
362 Class[] params1 = parameterTypes;
363 Class[] params2 = other.parameterTypes;
364 if (params1.length == params2.length) {
365 for (int i = 0; i < params1.length; i++) {
366 if (params1[i] != params2[i])
367 return false;
368 }
369 return true;
370 }
371 }
372 }
373 return false;
374 }
375
376 /**
377 * Returns a hashcode for this {@code Method}. The hashcode is computed
378 * as the exclusive-or of the hashcodes for the underlying
379 * method's declaring class name and the method's name.
380 */
381 public int hashCode() {
382 return getDeclaringClass().getName().hashCode()
383 ^ getName().hashCode();
384 }
385
386 /**
387 * Returns a string describing this {@code Method}. The string is
388 * formatted as the method access modifiers, if any, followed by
389 * the method return type, followed by a space, followed by the
390 * class declaring the method, followed by a period, followed by
391 * the method name, followed by a parenthesized, comma-separated
392 * list of the method's formal parameter types. If the method
393 * throws checked exceptions, the parameter list is followed by a
394 * space, followed by the word throws followed by a
395 * comma-separated list of the thrown exception types.
396 * For example:
397 * <pre>
398 * public boolean java.lang.Object.equals(java.lang.Object)
399 * </pre>
400 *
401 * <p>The access modifiers are placed in canonical order as
402 * specified by "The Java Language Specification". This is
403 * {@code public}, {@code protected} or {@code private} first,
404 * and then other modifiers in the following order:
405 * {@code abstract}, {@code static}, {@code final},
406 * {@code synchronized}, {@code native}.
407 */
408 public String toString() {
409 try {
410 StringBuffer sb = new StringBuffer();
411 int mod = getModifiers() & LANGUAGE_MODIFIERS;
412 if (mod != 0) {
413 sb.append(Modifier.toString(mod) + " ");
414 }
415 sb.append(Field.getTypeName(getReturnType()) + " ");
416 sb.append(Field.getTypeName(getDeclaringClass()) + ".");
417 sb.append(getName() + "(");
418 Class[] params = parameterTypes; // avoid clone
419 for (int j = 0; j < params.length; j++) {
420 sb.append(Field.getTypeName(params[j]));
421 if (j < (params.length - 1))
422 sb.append(",");
423 }
424 sb.append(")");
425 Class[] exceptions = exceptionTypes; // avoid clone
426 if (exceptions.length > 0) {
427 sb.append(" throws ");
428 for (int k = 0; k < exceptions.length; k++) {
429 sb.append(exceptions[k].getName());
430 if (k < (exceptions.length - 1))
431 sb.append(",");
432 }
433 }
434 return sb.toString();
435 } catch (Exception e) {
436 return "<" + e + ">";
437 }
438 }
439
440 /**
441 * Returns a string describing this {@code Method}, including
442 * type parameters. The string is formatted as the method access
443 * modifiers, if any, followed by an angle-bracketed
444 * comma-separated list of the method's type parameters, if any,
445 * followed by the method's generic return type, followed by a
446 * space, followed by the class declaring the method, followed by
447 * a period, followed by the method name, followed by a
448 * parenthesized, comma-separated list of the method's generic
449 * formal parameter types.
450 *
451 * If this method was declared to take a variable number of
452 * arguments, instead of denoting the last parameter as
453 * "<tt><i>Type</i>[]</tt>", it is denoted as
454 * "<tt><i>Type</i>...</tt>".
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<?>) ? Field
502 .getTypeName((Class<?>) genRetType) : genRetType
503 .toString())
504 + " ");
505
506 sb.append(Field.getTypeName(getDeclaringClass()) + ".");
507 sb.append(getName() + "(");
508 Type[] params = getGenericParameterTypes();
509 for (int j = 0; j < params.length; j++) {
510 String param = (params[j] instanceof Class) ? Field
511 .getTypeName((Class) params[j]) : (params[j]
512 .toString());
513 if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
514 param = param.replaceFirst("\\[\\]$", "...");
515 sb.append(param);
516 if (j < (params.length - 1))
517 sb.append(",");
518 }
519 sb.append(")");
520 Type[] exceptions = getGenericExceptionTypes();
521 if (exceptions.length > 0) {
522 sb.append(" throws ");
523 for (int k = 0; k < exceptions.length; k++) {
524 sb
525 .append((exceptions[k] instanceof Class) ? ((Class) exceptions[k])
526 .getName()
527 : exceptions[k].toString());
528 if (k < (exceptions.length - 1))
529 sb.append(",");
530 }
531 }
532 return sb.toString();
533 } catch (Exception e) {
534 return "<" + e + ">";
535 }
536 }
537
538 /**
539 * Invokes the underlying method represented by this {@code Method}
540 * object, on the specified object with the specified parameters.
541 * Individual parameters are automatically unwrapped to match
542 * primitive formal parameters, and both primitive and reference
543 * parameters are subject to method invocation conversions as
544 * necessary.
545 *
546 * <p>If the underlying method is static, then the specified {@code obj}
547 * argument is ignored. It may be null.
548 *
549 * <p>If the number of formal parameters required by the underlying method is
550 * 0, the supplied {@code args} array may be of length 0 or null.
551 *
552 * <p>If the underlying method is an instance method, it is invoked
553 * using dynamic method lookup as documented in The Java Language
554 * Specification, Second Edition, section 15.12.4.4; in particular,
555 * overriding based on the runtime type of the target object will occur.
556 *
557 * <p>If the underlying method is static, the class that declared
558 * the method is initialized if it has not already been initialized.
559 *
560 * <p>If the method completes normally, the value it returns is
561 * returned to the caller of invoke; if the value has a primitive
562 * type, it is first appropriately wrapped in an object. However,
563 * if the value has the type of an array of a primitive type, the
564 * elements of the array are <i>not</i> wrapped in objects; in
565 * other words, an array of primitive type is returned. If the
566 * underlying method return type is void, the invocation returns
567 * null.
568 *
569 * @param obj the object the underlying method is invoked from
570 * @param args the arguments used for the method call
571 * @return the result of dispatching the method represented by
572 * this object on {@code obj} with parameters
573 * {@code args}
574 *
575 * @exception IllegalAccessException if this {@code Method} object
576 * enforces Java language access control and the underlying
577 * method is inaccessible.
578 * @exception IllegalArgumentException if the method is an
579 * instance method and the specified object argument
580 * is not an instance of the class or interface
581 * declaring the underlying method (or of a subclass
582 * or implementor thereof); if the number of actual
583 * and formal parameters differ; if an unwrapping
584 * conversion for primitive arguments fails; or if,
585 * after possible unwrapping, a parameter value
586 * cannot be converted to the corresponding formal
587 * parameter type by a method invocation conversion.
588 * @exception InvocationTargetException if the underlying method
589 * throws an exception.
590 * @exception NullPointerException if the specified object is null
591 * and the method is an instance method.
592 * @exception ExceptionInInitializerError if the initialization
593 * provoked by this method fails.
594 */
595 public Object invoke(Object obj, Object... args)
596 throws IllegalAccessException, IllegalArgumentException,
597 InvocationTargetException {
598 if (!override) {
599 if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
600 Class caller = Reflection.getCallerClass(1);
601 Class targetClass = ((obj == null || !Modifier
602 .isProtected(modifiers)) ? clazz : obj
603 .getClass());
604
605 boolean cached;
606 synchronized (this ) {
607 cached = (securityCheckCache == caller)
608 && (securityCheckTargetClassCache == targetClass);
609 }
610 if (!cached) {
611 Reflection.ensureMemberAccess(caller, clazz, obj,
612 modifiers);
613 synchronized (this ) {
614 securityCheckCache = caller;
615 securityCheckTargetClassCache = targetClass;
616 }
617 }
618 }
619 }
620 if (methodAccessor == null)
621 acquireMethodAccessor();
622 return methodAccessor.invoke(obj, args);
623 }
624
625 /**
626 * Returns {@code true} if this method is a bridge
627 * method; returns {@code false} otherwise.
628 *
629 * @return true if and only if this method is a bridge
630 * method as defined by the Java Language Specification.
631 * @since 1.5
632 */
633 public boolean isBridge() {
634 return (getModifiers() & Modifier.BRIDGE) != 0;
635 }
636
637 /**
638 * Returns {@code true} if this method was declared to take
639 * a variable number of arguments; returns {@code false}
640 * otherwise.
641 *
642 * @return {@code true} if an only if this method was declared to
643 * take a variable number of arguments.
644 * @since 1.5
645 */
646 public boolean isVarArgs() {
647 return (getModifiers() & Modifier.VARARGS) != 0;
648 }
649
650 /**
651 * Returns {@code true} if this method is a synthetic
652 * method; returns {@code false} otherwise.
653 *
654 * @return true if and only if this method is a synthetic
655 * method as defined by the Java Language Specification.
656 * @since 1.5
657 */
658 public boolean isSynthetic() {
659 return Modifier.isSynthetic(getModifiers());
660 }
661
662 // NOTE that there is no synchronization used here. It is correct
663 // (though not efficient) to generate more than one MethodAccessor
664 // for a given Method. However, avoiding synchronization will
665 // probably make the implementation more scalable.
666 private void acquireMethodAccessor() {
667 // First check to see if one has been created yet, and take it
668 // if so
669 MethodAccessor tmp = null;
670 if (root != null)
671 tmp = root.getMethodAccessor();
672 if (tmp != null) {
673 methodAccessor = tmp;
674 return;
675 }
676 // Otherwise fabricate one and propagate it up to the root
677 tmp = reflectionFactory.newMethodAccessor(this );
678 setMethodAccessor(tmp);
679 }
680
681 // Returns MethodAccessor for this Method object, not looking up
682 // the chain to the root
683 MethodAccessor getMethodAccessor() {
684 return methodAccessor;
685 }
686
687 // Sets the MethodAccessor for this Method object and
688 // (recursively) its root
689 void setMethodAccessor(MethodAccessor accessor) {
690 methodAccessor = accessor;
691 // Propagate up
692 if (root != null) {
693 root.setMethodAccessor(accessor);
694 }
695 }
696
697 /**
698 * @throws NullPointerException {@inheritDoc}
699 * @since 1.5
700 */
701 public <T extends Annotation> T getAnnotation(
702 Class<T> annotationClass) {
703 if (annotationClass == null)
704 throw new NullPointerException();
705
706 return (T) declaredAnnotations().get(annotationClass);
707 }
708
709 private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
710
711 /**
712 * @since 1.5
713 */
714 public Annotation[] getDeclaredAnnotations() {
715 return declaredAnnotations().values().toArray(
716 EMPTY_ANNOTATION_ARRAY);
717 }
718
719 private transient Map<Class, Annotation> declaredAnnotations;
720
721 private synchronized Map<Class, Annotation> declaredAnnotations() {
722 if (declaredAnnotations == null) {
723 declaredAnnotations = AnnotationParser.parseAnnotations(
724 annotations, sun.misc.SharedSecrets
725 .getJavaLangAccess().getConstantPool(
726 getDeclaringClass()),
727 getDeclaringClass());
728 }
729 return declaredAnnotations;
730 }
731
732 /**
733 * Returns the default value for the annotation member represented by
734 * this {@code Method} instance. If the member is of a primitive type,
735 * an instance of the corresponding wrapper type is returned. Returns
736 * null if no default is associated with the member, or if the method
737 * instance does not represent a declared member of an annotation type.
738 *
739 * @return the default value for the annotation member represented
740 * by this {@code Method} instance.
741 * @throws TypeNotPresentException if the annotation is of type
742 * {@link Class} and no definition can be found for the
743 * default class value.
744 * @since 1.5
745 */
746 public Object getDefaultValue() {
747 if (annotationDefault == null)
748 return null;
749 Class memberType = AnnotationType
750 .invocationHandlerReturnType(getReturnType());
751 Object result = AnnotationParser.parseMemberValue(memberType,
752 ByteBuffer.wrap(annotationDefault),
753 sun.misc.SharedSecrets.getJavaLangAccess()
754 .getConstantPool(getDeclaringClass()),
755 getDeclaringClass());
756 if (result instanceof sun.reflect.annotation.ExceptionProxy)
757 throw new AnnotationFormatError("Invalid default: " + this );
758 return result;
759 }
760
761 /**
762 * Returns an array of arrays that represent the annotations on the formal
763 * parameters, in declaration order, of the method represented by
764 * this {@code Method} object. (Returns an array of length zero if the
765 * underlying method is parameterless. If the method has one or more
766 * parameters, a nested array of length zero is returned for each parameter
767 * with no annotations.) The annotation objects contained in the returned
768 * arrays are serializable. The caller of this method is free to modify
769 * the returned arrays; it will have no effect on the arrays returned to
770 * other callers.
771 *
772 * @return an array of arrays that represent the annotations on the formal
773 * parameters, in declaration order, of the method represented by this
774 * Method object
775 * @since 1.5
776 */
777 public Annotation[][] getParameterAnnotations() {
778 int numParameters = parameterTypes.length;
779 if (parameterAnnotations == null)
780 return new Annotation[numParameters][0];
781
782 Annotation[][] result = AnnotationParser
783 .parseParameterAnnotations(parameterAnnotations,
784 sun.misc.SharedSecrets.getJavaLangAccess()
785 .getConstantPool(getDeclaringClass()),
786 getDeclaringClass());
787 if (result.length != numParameters)
788 throw new java.lang.annotation.AnnotationFormatError(
789 "Parameter annotations don't match number of parameters");
790 return result;
791 }
792 }
|