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 * If this method was declared to take a variable number of
457 * arguments, instead of denoting the last parameter as
458 * "<tt><i>Type</i>[]</tt>", it is denoted as
459 * "<tt><i>Type</i>...</tt>".
460 *
461 * A space is used to separate access modifiers from one another
462 * and from the type parameters or return type. If there are no
463 * type parameters, the type parameter list is elided; if the type
464 * parameter list is present, a space separates the list from the
465 * class name. If the method is declared to throw exceptions, the
466 * parameter list is followed by a space, followed by the word
467 * throws followed by a comma-separated list of the generic thrown
468 * exception types. If there are no type parameters, the type
469 * parameter list is elided.
470 *
471 * <p>The access modifiers are placed in canonical order as
472 * specified by "The Java Language Specification". This is
473 * {@code public}, {@code protected} or {@code private} first,
474 * and then other modifiers in the following order:
475 * {@code abstract}, {@code static}, {@code final},
476 * {@code synchronized} {@code native}.
477 *
478 * @return a string describing this {@code Method},
479 * include type parameters
480 *
481 * @since 1.5
482 */
483 public String toGenericString() {
484 try {
485 StringBuilder sb = new StringBuilder();
486 int mod = getModifiers() & LANGUAGE_MODIFIERS;
487 if (mod != 0) {
488 sb.append(Modifier.toString(mod) + " ");
489 }
490 TypeVariable<?>[] typeparms = getTypeParameters();
491 if (typeparms.length > 0) {
492 boolean first = true;
493 sb.append("<");
494 for(TypeVariable<?> typeparm: typeparms) {
495 if (!first)
496 sb.append(",");
497 // Class objects can't occur here; no need to test
498 // and call Class.getName().
499 sb.append(typeparm.toString());
500 first = false;
501 }
502 sb.append("> ");
503 }
504
505 Type genRetType = getGenericReturnType();
506 sb.append( ((genRetType instanceof Class<?>)?
507 Field.getTypeName((Class<?>)genRetType):genRetType.toString()) + " ");
508
509 sb.append(Field.getTypeName(getDeclaringClass()) + ".");
510 sb.append(getName() + "(");
511 Type[] params = getGenericParameterTypes();
512 for (int j = 0; j < params.length; j++) {
513 String param = (params[j] instanceof Class)?
514 Field.getTypeName((Class)params[j]):
515 (params[j].toString());
516 if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
517 param = param.replaceFirst("\\[\\]$", "...");
518 sb.append(param);
519 if (j < (params.length - 1))
520 sb.append(",");
521 }
522 sb.append(")");
523 Type[] exceptions = getGenericExceptionTypes();
524 if (exceptions.length > 0) {
525 sb.append(" throws ");
526 for (int k = 0; k < exceptions.length; k++) {
527 sb.append((exceptions[k] instanceof Class)?
528 ((Class)exceptions[k]).getName():
529 exceptions[k].toString());
530 if (k < (exceptions.length - 1))
531 sb.append(",");
532 }
533 }
534 return sb.toString();
535 } catch (Exception e) {
536 return "<" + e + ">";
537 }
538 }
539
540 /**
541 * Invokes the underlying method represented by this {@code Method}
542 * object, on the specified object with the specified parameters.
543 * Individual parameters are automatically unwrapped to match
544 * primitive formal parameters, and both primitive and reference
545 * parameters are subject to method invocation conversions as
546 * necessary.
547 *
548 * <p>If the underlying method is static, then the specified {@code obj}
549 * argument is ignored. It may be null.
550 *
551 * <p>If the number of formal parameters required by the underlying method is
552 * 0, the supplied {@code args} array may be of length 0 or null.
553 *
554 * <p>If the underlying method is an instance method, it is invoked
555 * using dynamic method lookup as documented in The Java Language
556 * Specification, Second Edition, section 15.12.4.4; in particular,
557 * overriding based on the runtime type of the target object will occur.
558 *
559 * <p>If the underlying method is static, the class that declared
560 * the method is initialized if it has not already been initialized.
561 *
562 * <p>If the method completes normally, the value it returns is
563 * returned to the caller of invoke; if the value has a primitive
564 * type, it is first appropriately wrapped in an object. However,
565 * if the value has the type of an array of a primitive type, the
566 * elements of the array are <i>not</i> wrapped in objects; in
567 * other words, an array of primitive type is returned. If the
568 * underlying method return type is void, the invocation returns
569 * null.
570 *
571 * @param obj the object the underlying method is invoked from
572 * @param args the arguments used for the method call
573 * @return the result of dispatching the method represented by
574 * this object on {@code obj} with parameters
575 * {@code args}
576 *
577 * @exception IllegalAccessException if this {@code Method} object
578 * enforces Java language access control and the underlying
579 * method is inaccessible.
580 * @exception IllegalArgumentException if the method is an
581 * instance method and the specified object argument
582 * is not an instance of the class or interface
583 * declaring the underlying method (or of a subclass
584 * or implementor thereof); if the number of actual
585 * and formal parameters differ; if an unwrapping
586 * conversion for primitive arguments fails; or if,
587 * after possible unwrapping, a parameter value
588 * cannot be converted to the corresponding formal
589 * parameter type by a method invocation conversion.
590 * @exception InvocationTargetException if the underlying method
591 * throws an exception.
592 * @exception NullPointerException if the specified object is null
593 * and the method is an instance method.
594 * @exception ExceptionInInitializerError if the initialization
595 * provoked by this method fails.
596 */
597 public Object invoke(Object obj, Object... args)
598 throws IllegalAccessException, IllegalArgumentException,
599 InvocationTargetException
600 {
601 if (!override) {
602 if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
603 Class caller = Reflection.getCallerClass(1);
604 Class targetClass = ((obj == null || !Modifier.isProtected(modifiers))
605 ? clazz
606 : obj.getClass());
607
608 boolean cached;
609 synchronized (this) {
610 cached = (securityCheckCache == caller)
611 && (securityCheckTargetClassCache == targetClass);
612 }
613 if (!cached) {
614 Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
615 synchronized (this) {
616 securityCheckCache = caller;
617 securityCheckTargetClassCache = targetClass;
618 }
619 }
620 }
621 }
622 if (methodAccessor == null) acquireMethodAccessor();
623 return methodAccessor.invoke(obj, args);
624 }
625
626 /**
627 * Returns {@code true} if this method is a bridge
628 * method; returns {@code false} otherwise.
629 *
630 * @return true if and only if this method is a bridge
631 * method as defined by the Java Language Specification.
632 * @since 1.5
633 */
634 public boolean isBridge() {
635 return (getModifiers() & Modifier.BRIDGE) != 0;
636 }
637
638 /**
639 * Returns {@code true} if this method was declared to take
640 * a variable number of arguments; returns {@code false}
641 * otherwise.
642 *
643 * @return {@code true} if an only if this method was declared to
644 * take a variable number of arguments.
645 * @since 1.5
646 */
647 public boolean isVarArgs() {
648 return (getModifiers() & Modifier.VARARGS) != 0;
649 }
650
651 /**
652 * Returns {@code true} if this method is a synthetic
653 * method; returns {@code false} otherwise.
654 *
655 * @return true if and only if this method is a synthetic
656 * method as defined by the Java Language Specification.
657 * @since 1.5
658 */
659 public boolean isSynthetic() {
660 return Modifier.isSynthetic(getModifiers());
661 }
662
663 // NOTE that there is no synchronization used here. It is correct
664 // (though not efficient) to generate more than one MethodAccessor
665 // for a given Method. However, avoiding synchronization will
666 // probably make the implementation more scalable.
667 private void acquireMethodAccessor() {
668 // First check to see if one has been created yet, and take it
669 // if so
670 MethodAccessor tmp = null;
671 if (root != null) 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(Class<T> annotationClass) {
702 if (annotationClass == null)
703 throw new NullPointerException();
704
705 return (T) declaredAnnotations().get(annotationClass);
706 }
707
708 private static final Annotation[] EMPTY_ANNOTATION_ARRAY=new Annotation[0];
709
710 /**
711 * @since 1.5
712 */
713 public Annotation[] getDeclaredAnnotations() {
714 return declaredAnnotations().values().toArray(EMPTY_ANNOTATION_ARRAY);
715 }
716
717 private transient Map<Class, Annotation> declaredAnnotations;
718
719 private synchronized Map<Class, Annotation> declaredAnnotations() {
720 if (declaredAnnotations == null) {
721 declaredAnnotations = AnnotationParser.parseAnnotations(
722 annotations, sun.misc.SharedSecrets.getJavaLangAccess().
723 getConstantPool(getDeclaringClass()),
724 getDeclaringClass());
725 }
726 return declaredAnnotations;
727 }
728
729 /**
730 * Returns the default value for the annotation member represented by
731 * this {@code Method} instance. If the member is of a primitive type,
732 * an instance of the corresponding wrapper type is returned. Returns
733 * null if no default is associated with the member, or if the method
734 * instance does not represent a declared member of an annotation type.
735 *
736 * @return the default value for the annotation member represented
737 * by this {@code Method} instance.
738 * @throws TypeNotPresentException if the annotation is of type
739 * {@link Class} and no definition can be found for the
740 * default class value.
741 * @since 1.5
742 */
743 public Object getDefaultValue() {
744 if (annotationDefault == null)
745 return null;
746 Class memberType = AnnotationType.invocationHandlerReturnType(
747 getReturnType());
748 Object result = AnnotationParser.parseMemberValue(
749 memberType, ByteBuffer.wrap(annotationDefault),
750 sun.misc.SharedSecrets.getJavaLangAccess().
751 getConstantPool(getDeclaringClass()),
752 getDeclaringClass());
753 if (result instanceof sun.reflect.annotation.ExceptionProxy)
754 throw new AnnotationFormatError("Invalid default: " + this);
755 return result;
756 }
757
758 /**
759 * Returns an array of arrays that represent the annotations on the formal
760 * parameters, in declaration order, of the method represented by
761 * this {@code Method} object. (Returns an array of length zero if the
762 * underlying method is parameterless. If the method has one or more
763 * parameters, a nested array of length zero is returned for each parameter
764 * with no annotations.) The annotation objects contained in the returned
765 * arrays are serializable. The caller of this method is free to modify
766 * the returned arrays; it will have no effect on the arrays returned to
767 * other callers.
768 *
769 * @return an array of arrays that represent the annotations on the formal
770 * parameters, in declaration order, of the method represented by this
771 * Method object
772 * @since 1.5
773 */
774 public Annotation[][] getParameterAnnotations() {
775 int numParameters = parameterTypes.length;
776 if (parameterAnnotations == null)
777 return new Annotation[numParameters][0];
778
779 Annotation[][] result = AnnotationParser.parseParameterAnnotations(
780 parameterAnnotations,
781 sun.misc.SharedSecrets.getJavaLangAccess().
782 getConstantPool(getDeclaringClass()),
783 getDeclaringClass());
784 if (result.length != numParameters)
785 throw new java.lang.annotation.AnnotationFormatError(
786 "Parameter annotations don't match number of parameters");
787 return result;
788 }
789 }