34 import sun.reflect.annotation.AnnotationType; |
34 import sun.reflect.annotation.AnnotationType; |
35 import sun.reflect.annotation.AnnotationParser; |
35 import sun.reflect.annotation.AnnotationParser; |
36 import java.lang.annotation.Annotation; |
36 import java.lang.annotation.Annotation; |
37 import java.lang.annotation.AnnotationFormatError; |
37 import java.lang.annotation.AnnotationFormatError; |
38 import java.nio.ByteBuffer; |
38 import java.nio.ByteBuffer; |
39 import java.util.Map; |
|
40 |
39 |
41 /** |
40 /** |
42 * A {@code Method} provides information about, and access to, a single method |
41 * 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 |
42 * on a class or interface. The reflected method may be a class method |
44 * or an instance method (including an abstract method). |
43 * or an instance method (including an abstract method). |
81 // For sharing of MethodAccessors. This branching structure is |
78 // For sharing of MethodAccessors. This branching structure is |
82 // currently only two levels deep (i.e., one root Method and |
79 // currently only two levels deep (i.e., one root Method and |
83 // potentially many Method objects pointing to it.) |
80 // potentially many Method objects pointing to it.) |
84 private Method root; |
81 private Method root; |
85 |
82 |
86 // Generics infrastructure |
83 |
87 |
84 // Generics infrastructure |
88 private String getGenericSignature() {return signature;} |
85 private String getGenericSignature() {return signature;} |
89 |
86 |
90 // Accessor for factory |
87 // Accessor for factory |
91 private GenericsFactory getFactory() { |
88 private GenericsFactory getFactory() { |
92 // create scope and factory |
89 // create scope and factory |
93 return CoreReflectionFactory.make(this, MethodScope.make(this)); |
90 return CoreReflectionFactory.make(this, MethodScope.make(this)); |
94 } |
91 } |
95 |
92 |
96 // Accessor for generic info repository |
93 // Accessor for generic info repository |
97 private MethodRepository getGenericInfo() { |
94 @Override |
|
95 MethodRepository getGenericInfo() { |
98 // lazily initialize repository if necessary |
96 // lazily initialize repository if necessary |
99 if (genericInfo == null) { |
97 if (genericInfo == null) { |
100 // create and cache generic info repository |
98 // create and cache generic info repository |
101 genericInfo = MethodRepository.make(getGenericSignature(), |
99 genericInfo = MethodRepository.make(getGenericSignature(), |
102 getFactory()); |
100 getFactory()); |
154 // Might as well eagerly propagate this if already present |
151 // Might as well eagerly propagate this if already present |
155 res.methodAccessor = methodAccessor; |
152 res.methodAccessor = methodAccessor; |
156 return res; |
153 return res; |
157 } |
154 } |
158 |
155 |
159 /** |
156 @Override |
160 * Returns the {@code Class} object representing the class or interface |
157 boolean hasGenericInformation() { |
161 * that declares the method represented by this {@code Method} object. |
158 return (getGenericSignature() != null); |
162 */ |
159 } |
|
160 |
|
161 @Override |
|
162 byte[] getAnnotationBytes() { |
|
163 return annotations; |
|
164 } |
|
165 |
|
166 /** |
|
167 * {@inheritDoc} |
|
168 */ |
|
169 @Override |
163 public Class<?> getDeclaringClass() { |
170 public Class<?> getDeclaringClass() { |
164 return clazz; |
171 return clazz; |
165 } |
172 } |
166 |
173 |
167 /** |
174 /** |
168 * Returns the name of the method represented by this {@code Method} |
175 * Returns the name of the method represented by this {@code Method} |
169 * object, as a {@code String}. |
176 * object, as a {@code String}. |
170 */ |
177 */ |
|
178 @Override |
171 public String getName() { |
179 public String getName() { |
172 return name; |
180 return name; |
173 } |
181 } |
174 |
182 |
175 /** |
183 /** |
176 * Returns the Java language modifiers for the method represented |
184 * {@inheritDoc} |
177 * by this {@code Method} object, as an integer. The {@code Modifier} class should |
185 */ |
178 * be used to decode the modifiers. |
186 @Override |
179 * |
|
180 * @see Modifier |
|
181 */ |
|
182 public int getModifiers() { |
187 public int getModifiers() { |
183 return modifiers; |
188 return modifiers; |
184 } |
189 } |
185 |
190 |
186 /** |
191 /** |
187 * Returns an array of {@code TypeVariable} objects that represent the |
192 * {@inheritDoc} |
188 * type variables declared by the generic declaration represented by this |
193 * @throws GenericSignatureFormatError {@inheritDoc} |
189 * {@code GenericDeclaration} object, in declaration order. Returns an |
194 * @since 1.5 |
190 * array of length 0 if the underlying generic declaration declares no type |
195 */ |
191 * variables. |
196 @Override |
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™ Virtual Machine Specification</cite> |
|
199 * @since 1.5 |
|
200 */ |
|
201 public TypeVariable<Method>[] getTypeParameters() { |
197 public TypeVariable<Method>[] getTypeParameters() { |
202 if (getGenericSignature() != null) |
198 if (getGenericSignature() != null) |
203 return (TypeVariable<Method>[])getGenericInfo().getTypeParameters(); |
199 return (TypeVariable<Method>[])getGenericInfo().getTypeParameters(); |
204 else |
200 else |
205 return (TypeVariable<Method>[])new TypeVariable[0]; |
201 return (TypeVariable<Method>[])new TypeVariable[0]; |
243 if (getGenericSignature() != null) { |
239 if (getGenericSignature() != null) { |
244 return getGenericInfo().getReturnType(); |
240 return getGenericInfo().getReturnType(); |
245 } else { return getReturnType();} |
241 } else { return getReturnType();} |
246 } |
242 } |
247 |
243 |
248 |
244 /** |
249 /** |
245 * {@inheritDoc} |
250 * Returns an array of {@code Class} objects that represent the formal |
246 */ |
251 * parameter types, in declaration order, of the method |
247 @Override |
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() { |
248 public Class<?>[] getParameterTypes() { |
259 return (Class<?>[]) parameterTypes.clone(); |
249 return (Class<?>[]) parameterTypes.clone(); |
260 } |
250 } |
261 |
251 |
262 /** |
252 /** |
263 * Returns an array of {@code Type} objects that represent the formal |
253 * {@inheritDoc} |
264 * parameter types, in declaration order, of the method represented by |
254 * @throws GenericSignatureFormatError {@inheritDoc} |
265 * this {@code Method} object. Returns an array of length 0 if the |
255 * @throws TypeNotPresentException {@inheritDoc} |
266 * underlying method takes no parameters. |
256 * @throws MalformedParameterizedTypeException {@inheritDoc} |
267 * |
257 * @since 1.5 |
268 * <p>If a formal parameter type is a parameterized type, |
258 */ |
269 * the {@code Type} object returned for it must accurately reflect |
259 @Override |
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™ 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() { |
260 public Type[] getGenericParameterTypes() { |
290 if (getGenericSignature() != null) |
261 return super.getGenericParameterTypes(); |
291 return getGenericInfo().getParameterTypes(); |
262 } |
292 else |
263 |
293 return getParameterTypes(); |
264 /** |
294 } |
265 * {@inheritDoc} |
295 |
266 */ |
296 |
267 @Override |
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() { |
268 public Class<?>[] getExceptionTypes() { |
308 return (Class<?>[]) exceptionTypes.clone(); |
269 return (Class<?>[]) exceptionTypes.clone(); |
309 } |
270 } |
310 |
271 |
311 /** |
272 /** |
312 * Returns an array of {@code Type} objects that represent the |
273 * {@inheritDoc} |
313 * exceptions declared to be thrown by this {@code Method} object. |
274 * @throws GenericSignatureFormatError {@inheritDoc} |
314 * Returns an array of length 0 if the underlying method declares |
275 * @throws TypeNotPresentException {@inheritDoc} |
315 * no exceptions in its {@code throws} clause. |
276 * @throws MalformedParameterizedTypeException {@inheritDoc} |
316 * |
277 * @since 1.5 |
317 * <p>If an exception type is a type variable or a parameterized |
278 */ |
318 * type, it is created. Otherwise, it is resolved. |
279 @Override |
319 * |
280 public Type[] getGenericExceptionTypes() { |
320 * @return an array of Types that represent the exception types |
281 return super.getGenericExceptionTypes(); |
321 * thrown by the underlying method |
282 } |
322 * @throws GenericSignatureFormatError |
|
323 * if the generic method signature does not conform to the format |
|
324 * specified in |
|
325 * <cite>The Java™ 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 |
283 |
342 /** |
284 /** |
343 * Compares this {@code Method} against the specified object. Returns |
285 * Compares this {@code Method} against the specified object. Returns |
344 * true if the objects are the same. Two {@code Methods} are the same if |
286 * 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 |
287 * they were declared by the same class and have the same name |
397 * and then other modifiers in the following order: |
330 * and then other modifiers in the following order: |
398 * {@code abstract}, {@code static}, {@code final}, |
331 * {@code abstract}, {@code static}, {@code final}, |
399 * {@code synchronized}, {@code native}, {@code strictfp}. |
332 * {@code synchronized}, {@code native}, {@code strictfp}. |
400 */ |
333 */ |
401 public String toString() { |
334 public String toString() { |
402 try { |
335 return sharedToString(Modifier.methodModifiers(), |
403 StringBuilder sb = new StringBuilder(); |
336 parameterTypes, |
404 int mod = getModifiers() & Modifier.methodModifiers(); |
337 exceptionTypes); |
405 if (mod != 0) { |
338 } |
406 sb.append(Modifier.toString(mod)).append(' '); |
339 |
407 } |
340 @Override |
408 sb.append(Field.getTypeName(getReturnType())).append(' '); |
341 void specificToStringHeader(StringBuilder sb) { |
409 sb.append(Field.getTypeName(getDeclaringClass())).append('.'); |
342 sb.append(Field.getTypeName(getReturnType())).append(' '); |
410 sb.append(getName()).append('('); |
343 sb.append(Field.getTypeName(getDeclaringClass())).append('.'); |
411 Class<?>[] params = parameterTypes; // avoid clone |
344 sb.append(getName()); |
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 } |
345 } |
432 |
346 |
433 /** |
347 /** |
434 * Returns a string describing this {@code Method}, including |
348 * Returns a string describing this {@code Method}, including |
435 * type parameters. The string is formatted as the method access |
349 * type parameters. The string is formatted as the method access |
466 * @return a string describing this {@code Method}, |
380 * @return a string describing this {@code Method}, |
467 * include type parameters |
381 * include type parameters |
468 * |
382 * |
469 * @since 1.5 |
383 * @since 1.5 |
470 */ |
384 */ |
|
385 @Override |
471 public String toGenericString() { |
386 public String toGenericString() { |
472 try { |
387 return sharedToGenericString(Modifier.methodModifiers()); |
473 StringBuilder sb = new StringBuilder(); |
388 } |
474 int mod = getModifiers() & Modifier.methodModifiers(); |
389 |
475 if (mod != 0) { |
390 @Override |
476 sb.append(Modifier.toString(mod)).append(' '); |
391 void specificToGenericStringHeader(StringBuilder sb) { |
477 } |
392 Type genRetType = getGenericReturnType(); |
478 TypeVariable<?>[] typeparms = getTypeParameters(); |
393 sb.append( ((genRetType instanceof Class<?>)? |
479 if (typeparms.length > 0) { |
394 Field.getTypeName((Class<?>)genRetType):genRetType.toString())) |
480 boolean first = true; |
395 .append(' '); |
481 sb.append('<'); |
396 |
482 for(TypeVariable<?> typeparm: typeparms) { |
397 sb.append(Field.getTypeName(getDeclaringClass())).append('.'); |
483 if (!first) |
398 sb.append(getName()); |
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 } |
399 } |
528 |
400 |
529 /** |
401 /** |
530 * Invokes the underlying method represented by this {@code Method} |
402 * Invokes the underlying method represented by this {@code Method} |
531 * object, on the specified object with the specified parameters. |
403 * object, on the specified object with the specified parameters. |
612 public boolean isBridge() { |
484 public boolean isBridge() { |
613 return (getModifiers() & Modifier.BRIDGE) != 0; |
485 return (getModifiers() & Modifier.BRIDGE) != 0; |
614 } |
486 } |
615 |
487 |
616 /** |
488 /** |
617 * Returns {@code true} if this method was declared to take |
489 * {@inheritDoc} |
618 * a variable number of arguments; returns {@code false} |
490 * @since 1.5 |
619 * otherwise. |
491 */ |
620 * |
492 @Override |
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() { |
493 public boolean isVarArgs() { |
626 return (getModifiers() & Modifier.VARARGS) != 0; |
494 return super.isVarArgs(); |
627 } |
495 } |
628 |
496 |
629 /** |
497 /** |
630 * Returns {@code true} if this method is a synthetic |
498 * {@inheritDoc} |
631 * method; returns {@code false} otherwise. |
499 * @since 1.5 |
632 * |
500 */ |
633 * @return true if and only if this method is a synthetic |
501 @Override |
634 * method as defined by the Java Language Specification. |
|
635 * @since 1.5 |
|
636 */ |
|
637 public boolean isSynthetic() { |
502 public boolean isSynthetic() { |
638 return Modifier.isSynthetic(getModifiers()); |
503 return super.isSynthetic(); |
639 } |
504 } |
640 |
505 |
641 // NOTE that there is no synchronization used here. It is correct |
506 // NOTE that there is no synchronization used here. It is correct |
642 // (though not efficient) to generate more than one MethodAccessor |
507 // (though not efficient) to generate more than one MethodAccessor |
643 // for a given Method. However, avoiding synchronization will |
508 // for a given Method. However, avoiding synchronization will |
673 root.setMethodAccessor(accessor); |
538 root.setMethodAccessor(accessor); |
674 } |
539 } |
675 } |
540 } |
676 |
541 |
677 /** |
542 /** |
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 |
543 * Returns the default value for the annotation member represented by |
709 * this {@code Method} instance. If the member is of a primitive type, |
544 * this {@code Method} instance. If the member is of a primitive type, |
710 * an instance of the corresponding wrapper type is returned. Returns |
545 * an instance of the corresponding wrapper type is returned. Returns |
711 * null if no default is associated with the member, or if the method |
546 * 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. |
547 * instance does not represent a declared member of an annotation type. |
732 throw new AnnotationFormatError("Invalid default: " + this); |
567 throw new AnnotationFormatError("Invalid default: " + this); |
733 return result; |
568 return result; |
734 } |
569 } |
735 |
570 |
736 /** |
571 /** |
737 * Returns an array of arrays that represent the annotations on the formal |
572 * {@inheritDoc} |
738 * parameters, in declaration order, of the method represented by |
573 * @throws NullPointerException {@inheritDoc} |
739 * this {@code Method} object. (Returns an array of length zero if the |
574 * @since 1.5 |
740 * underlying method is parameterless. If the method has one or more |
575 */ |
741 * parameters, a nested array of length zero is returned for each parameter |
576 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { |
742 * with no annotations.) The annotation objects contained in the returned |
577 return super.getAnnotation(annotationClass); |
743 * arrays are serializable. The caller of this method is free to modify |
578 } |
744 * the returned arrays; it will have no effect on the arrays returned to |
579 |
745 * other callers. |
580 /** |
746 * |
581 * {@inheritDoc} |
747 * @return an array of arrays that represent the annotations on the formal |
582 * @since 1.5 |
748 * parameters, in declaration order, of the method represented by this |
583 */ |
749 * Method object |
584 public Annotation[] getDeclaredAnnotations() { |
750 * @since 1.5 |
585 return super.getDeclaredAnnotations(); |
751 */ |
586 } |
|
587 |
|
588 /** |
|
589 * {@inheritDoc} |
|
590 * @since 1.5 |
|
591 */ |
|
592 @Override |
752 public Annotation[][] getParameterAnnotations() { |
593 public Annotation[][] getParameterAnnotations() { |
753 int numParameters = parameterTypes.length; |
594 return sharedGetParameterAnnotations(parameterTypes, parameterAnnotations); |
754 if (parameterAnnotations == null) |
595 } |
755 return new Annotation[numParameters][0]; |
596 |
756 |
597 @Override |
757 Annotation[][] result = AnnotationParser.parseParameterAnnotations( |
598 void handleParameterNumberMismatch(int resultLength, int numParameters) { |
758 parameterAnnotations, |
599 throw new AnnotationFormatError("Parameter annotations don't match number of parameters"); |
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 } |
600 } |
767 } |
601 } |