1 /*
2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 *
5 *
6 *
7 *
8 *
9 *
10 *
11 *
12 *
13 *
14 *
15 *
16 *
17 *
18 *
19 *
20 *
21 *
22 *
23 *
24 */
25
26 package java.lang.reflect;
27
28 import java.lang.annotation.*;
29 import java.util.Map;
30 import java.util.Objects;
31 import sun.reflect.annotation.AnnotationParser;
32 import sun.reflect.annotation.AnnotationSupport;
33 import sun.reflect.annotation.TypeAnnotationParser;
34 import sun.reflect.annotation.TypeAnnotation;
35 import sun.reflect.generics.repository.ConstructorRepository;
36
37 /**
38 * A shared superclass for the common functionality of {@link Method}
39 * and {@link Constructor}.
40 *
41 * @since 1.8
42 */
43 public abstract class Executable extends AccessibleObject
44 implements Member, GenericDeclaration {
45 /*
46 * Only grant package-visibility to the constructor.
47 */
48 Executable() {}
49
50 /**
51 * Accessor method to allow code sharing
52 */
53 abstract byte[] getAnnotationBytes();
54
55 /**
56 * Accessor method to allow code sharing
57 */
58 abstract Executable getRoot();
59
60 /**
61 * Does the Executable have generic information.
62 */
63 abstract boolean hasGenericInformation();
64
65 abstract ConstructorRepository getGenericInfo();
66
67 boolean equalParamTypes(Class<?>[] params1, Class<?>[] params2) {
68 /* Avoid unnecessary cloning */
69 if (params1.length == params2.length) {
70 for (int i = 0; i < params1.length; i++) {
71 if (params1[i] != params2[i])
72 return false;
73 }
74 return true;
75 }
76 return false;
77 }
78
79 Annotation[][] parseParameterAnnotations(byte[] parameterAnnotations) {
80 return AnnotationParser.parseParameterAnnotations(
81 parameterAnnotations,
82 sun.misc.SharedSecrets.getJavaLangAccess().
83 getConstantPool(getDeclaringClass()),
84 getDeclaringClass());
85 }
86
87 void separateWithCommas(Class<?>[] types, StringBuilder sb) {
88 for (int j = 0; j < types.length; j++) {
89 sb.append(types[j].getTypeName());
90 if (j < (types.length - 1))
91 sb.append(",");
92 }
93
94 }
95
96 void printModifiersIfNonzero(StringBuilder sb, int mask, boolean isDefault) {
97 int mod = getModifiers() & mask;
98
99 if (mod != 0 && !isDefault) {
100 sb.append(Modifier.toString(mod)).append(' ');
101 } else {
102 int access_mod = mod & Modifier.ACCESS_MODIFIERS;
103 if (access_mod != 0)
104 sb.append(Modifier.toString(access_mod)).append(' ');
105 if (isDefault)
106 sb.append("default ");
107 mod = (mod & ~Modifier.ACCESS_MODIFIERS);
108 if (mod != 0)
109 sb.append(Modifier.toString(mod)).append(' ');
110 }
111 }
112
113 String sharedToString(int modifierMask,
114 boolean isDefault,
115 Class<?>[] parameterTypes,
116 Class<?>[] exceptionTypes) {
117 try {
118 StringBuilder sb = new StringBuilder();
119
120 printModifiersIfNonzero(sb, modifierMask, isDefault);
121 specificToStringHeader(sb);
122
123 sb.append('(');
124 separateWithCommas(parameterTypes, sb);
125 sb.append(')');
126 if (exceptionTypes.length > 0) {
127 sb.append(" throws ");
128 separateWithCommas(exceptionTypes, sb);
129 }
130 return sb.toString();
131 } catch (Exception e) {
132 return "<" + e + ">";
133 }
134 }
135
136 /**
137 * Generate toString header information specific to a method or
138 * constructor.
139 */
140 abstract void specificToStringHeader(StringBuilder sb);
141
142 String sharedToGenericString(int modifierMask, boolean isDefault) {
143 try {
144 StringBuilder sb = new StringBuilder();
145
146 printModifiersIfNonzero(sb, modifierMask, isDefault);
147
148 TypeVariable<?>[] typeparms = getTypeParameters();
149 if (typeparms.length > 0) {
150 boolean first = true;
151 sb.append('<');
152 for(TypeVariable<?> typeparm: typeparms) {
153 if (!first)
154 sb.append(',');
155 // Class objects can't occur here; no need to test
156 // and call Class.getName().
157 sb.append(typeparm.toString());
158 first = false;
159 }
160 sb.append("> ");
161 }
162
163 specificToGenericStringHeader(sb);
164
165 sb.append('(');
166 Type[] params = getGenericParameterTypes();
167 for (int j = 0; j < params.length; j++) {
168 String param = params[j].getTypeName();
169 if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
170 param = param.replaceFirst("\\[\\]$", "...");
171 sb.append(param);
172 if (j < (params.length - 1))
173 sb.append(',');
174 }
175 sb.append(')');
176 Type[] exceptions = getGenericExceptionTypes();
177 if (exceptions.length > 0) {
178 sb.append(" throws ");
179 for (int k = 0; k < exceptions.length; k++) {
180 sb.append((exceptions[k] instanceof Class)?
181 ((Class)exceptions[k]).getName():
182 exceptions[k].toString());
183 if (k < (exceptions.length - 1))
184 sb.append(',');
185 }
186 }
187 return sb.toString();
188 } catch (Exception e) {
189 return "<" + e + ">";
190 }
191 }
192
193 /**
194 * Generate toGenericString header information specific to a
195 * method or constructor.
196 */
197 abstract void specificToGenericStringHeader(StringBuilder sb);
198
199 /**
200 * Returns the {@code Class} object representing the class or interface
201 * that declares the executable represented by this object.
202 */
203 public abstract Class<?> getDeclaringClass();
204
205 /**
206 * Returns the name of the executable represented by this object.
207 */
208 public abstract String getName();
209
210 /**
211 * Returns the Java language {@linkplain Modifier modifiers} for
212 * the executable represented by this object.
213 */
214 public abstract int getModifiers();
215
216 /**
217 * Returns an array of {@code TypeVariable} objects that represent the
218 * type variables declared by the generic declaration represented by this
219 * {@code GenericDeclaration} object, in declaration order. Returns an
220 * array of length 0 if the underlying generic declaration declares no type
221 * variables.
222 *
223 * @return an array of {@code TypeVariable} objects that represent
224 * the type variables declared by this generic declaration
225 * @throws GenericSignatureFormatError if the generic
226 * signature of this generic declaration does not conform to
227 * the format specified in
228 * <cite>The Java™ Virtual Machine Specification</cite>
229 */
230 public abstract TypeVariable<?>[] getTypeParameters();
231
232 /**
233 * Returns an array of {@code Class} objects that represent the formal
234 * parameter types, in declaration order, of the executable
235 * represented by this object. Returns an array of length
236 * 0 if the underlying executable takes no parameters.
237 *
238 * @return the parameter types for the executable this object
239 * represents
240 */
241 public abstract Class<?>[] getParameterTypes();
242
243 /**
244 * Returns the number of formal parameters (whether explicitly
245 * declared or implicitly declared or neither) for the executable
246 * represented by this object.
247 *
248 * @return The number of formal parameters for the executable this
249 * object represents
250 */
251 public int getParameterCount() {
252 throw new AbstractMethodError();
253 }
254
255 /**
256 * Returns an array of {@code Type} objects that represent the formal
257 * parameter types, in declaration order, of the executable represented by
258 * this object. Returns an array of length 0 if the
259 * underlying executable takes no parameters.
260 *
261 * <p>If a formal parameter type is a parameterized type,
262 * the {@code Type} object returned for it must accurately reflect
263 * the actual type parameters used in the source code.
264 *
265 * <p>If a formal parameter type is a type variable or a parameterized
266 * type, it is created. Otherwise, it is resolved.
267 *
268 * @return an array of {@code Type}s that represent the formal
269 * parameter types of the underlying executable, in declaration order
270 * @throws GenericSignatureFormatError
271 * if the generic method signature does not conform to the format
272 * specified in
273 * <cite>The Java™ Virtual Machine Specification</cite>
274 * @throws TypeNotPresentException if any of the parameter
275 * types of the underlying executable refers to a non-existent type
276 * declaration
277 * @throws MalformedParameterizedTypeException if any of
278 * the underlying executable's parameter types refer to a parameterized
279 * type that cannot be instantiated for any reason
280 */
281 public Type[] getGenericParameterTypes() {
282 if (hasGenericInformation())
283 return getGenericInfo().getParameterTypes();
284 else
285 return getParameterTypes();
286 }
287
288 /**
289 * Behaves like {@code getGenericParameterTypes}, but returns type
290 * information for all parameters, including synthetic parameters.
291 */
292 Type[] getAllGenericParameterTypes() {
293 final boolean genericInfo = hasGenericInformation();
294
295 // Easy case: we don't have generic parameter information. In
296 // this case, we just return the result of
297 // getParameterTypes().
298 if (!genericInfo) {
299 return getParameterTypes();
300 } else {
301 final boolean realParamData = hasRealParameterData();
302 final Type[] genericParamTypes = getGenericParameterTypes();
303 final Type[] nonGenericParamTypes = getParameterTypes();
304 final Type[] out = new Type[nonGenericParamTypes.length];
305 final Parameter[] params = getParameters();
306 int fromidx = 0;
307 // If we have real parameter data, then we use the
308 // synthetic and mandate flags to our advantage.
309 if (realParamData) {
310 for (int i = 0; i < out.length; i++) {
311 final Parameter param = params[i];
312 if (param.isSynthetic() || param.isImplicit()) {
313 // If we hit a synthetic or mandated parameter,
314 // use the non generic parameter info.
315 out[i] = nonGenericParamTypes[i];
316 } else {
317 // Otherwise, use the generic parameter info.
318 out[i] = genericParamTypes[fromidx];
319 fromidx++;
320 }
321 }
322 } else {
323 // Otherwise, use the non-generic parameter data.
324 // Without method parameter reflection data, we have
325 // no way to figure out which parameters are
326 // synthetic/mandated, thus, no way to match up the
327 // indexes.
328 return genericParamTypes.length == nonGenericParamTypes.length ?
329 genericParamTypes : nonGenericParamTypes;
330 }
331 return out;
332 }
333 }
334
335 /**
336 * Returns an array of {@code Parameter} objects that represent
337 * all the parameters to the underlying executable represented by
338 * this object. Returns an array of length 0 if the executable
339 * has no parameters.
340 *
341 * <p>The parameters of the underlying executable do not necessarily
342 * have unique names, or names that are legal identifiers in the
343 * Java programming language (JLS 3.8).
344 *
345 * @throws MalformedParametersException if the class file contains
346 * a MethodParameters attribute that is improperly formatted.
347 * @return an array of {@code Parameter} objects representing all
348 * the parameters to the executable this object represents.
349 */
350 public Parameter[] getParameters() {
351 // TODO: This may eventually need to be guarded by security
352 // mechanisms similar to those in Field, Method, etc.
353 //
354 // Need to copy the cached array to prevent users from messing
355 // with it. Since parameters are immutable, we can
356 // shallow-copy.
357 return privateGetParameters().clone();
358 }
359
360 private Parameter[] synthesizeAllParams() {
361 final int realparams = getParameterCount();
362 final Parameter[] out = new Parameter[realparams];
363 for (int i = 0; i < realparams; i++)
364 // TODO: is there a way to synthetically derive the
365 // modifiers? Probably not in the general case, since
366 // we'd have no way of knowing about them, but there
367 // may be specific cases.
368 out[i] = new Parameter("arg" + i, 0, this, i);
369 return out;
370 }
371
372 private void verifyParameters(final Parameter[] parameters) {
373 final int mask = Modifier.FINAL | Modifier.SYNTHETIC | Modifier.MANDATED;
374
375 if (getParameterTypes().length != parameters.length)
376 throw new MalformedParametersException("Wrong number of parameters in MethodParameters attribute");
377
378 for (Parameter parameter : parameters) {
379 final String name = parameter.getRealName();
380 final int mods = parameter.getModifiers();
381
382 if (name != null) {
383 if (name.isEmpty() || name.indexOf('.') != -1 ||
384 name.indexOf(';') != -1 || name.indexOf('[') != -1 ||
385 name.indexOf('/') != -1) {
386 throw new MalformedParametersException("Invalid parameter name \"" + name + "\"");
387 }
388 }
389
390 if (mods != (mods & mask)) {
391 throw new MalformedParametersException("Invalid parameter modifiers");
392 }
393 }
394 }
395
396 private Parameter[] privateGetParameters() {
397 // Use tmp to avoid multiple writes to a volatile.
398 Parameter[] tmp = parameters;
399
400 if (tmp == null) {
401
402 // Otherwise, go to the JVM to get them
403 try {
404 tmp = getParameters0();
405 } catch(IllegalArgumentException e) {
406 // Rethrow ClassFormatErrors
407 throw new MalformedParametersException("Invalid constant pool index");
408 }
409
410 // If we get back nothing, then synthesize parameters
411 if (tmp == null) {
412 hasRealParameterData = false;
413 tmp = synthesizeAllParams();
414 } else {
415 hasRealParameterData = true;
416 verifyParameters(tmp);
417 }
418
419 parameters = tmp;
420 }
421
422 return tmp;
423 }
424
425 boolean hasRealParameterData() {
426 // If this somehow gets called before parameters gets
427 // initialized, force it into existence.
428 if (parameters == null) {
429 privateGetParameters();
430 }
431 return hasRealParameterData;
432 }
433
434 private transient volatile boolean hasRealParameterData;
435 private transient volatile Parameter[] parameters;
436
437 private native Parameter[] getParameters0();
438 native byte[] getTypeAnnotationBytes0();
439
440 // Needed by reflectaccess
441 byte[] getTypeAnnotationBytes() {
442 return getTypeAnnotationBytes0();
443 }
444
445 /**
446 * Returns an array of {@code Class} objects that represent the
447 * types of exceptions declared to be thrown by the underlying
448 * executable represented by this object. Returns an array of
449 * length 0 if the executable declares no exceptions in its {@code
450 * throws} clause.
451 *
452 * @return the exception types declared as being thrown by the
453 * executable this object represents
454 */
455 public abstract Class<?>[] getExceptionTypes();
456
457 /**
458 * Returns an array of {@code Type} objects that represent the
459 * exceptions declared to be thrown by this executable object.
460 * Returns an array of length 0 if the underlying executable declares
461 * no exceptions in its {@code throws} clause.
462 *
463 * <p>If an exception type is a type variable or a parameterized
464 * type, it is created. Otherwise, it is resolved.
465 *
466 * @return an array of Types that represent the exception types
467 * thrown by the underlying executable
468 * @throws GenericSignatureFormatError
469 * if the generic method signature does not conform to the format
470 * specified in
471 * <cite>The Java™ Virtual Machine Specification</cite>
472 * @throws TypeNotPresentException if the underlying executable's
473 * {@code throws} clause refers to a non-existent type declaration
474 * @throws MalformedParameterizedTypeException if
475 * the underlying executable's {@code throws} clause refers to a
476 * parameterized type that cannot be instantiated for any reason
477 */
478 public Type[] getGenericExceptionTypes() {
479 Type[] result;
480 if (hasGenericInformation() &&
481 ((result = getGenericInfo().getExceptionTypes()).length > 0))
482 return result;
483 else
484 return getExceptionTypes();
485 }
486
487 /**
488 * Returns a string describing this {@code Executable}, including
489 * any type parameters.
490 * @return a string describing this {@code Executable}, including
491 * any type parameters
492 */
493 public abstract String toGenericString();
494
495 /**
496 * Returns {@code true} if this executable was declared to take a
497 * variable number of arguments; returns {@code false} otherwise.
498 *
499 * @return {@code true} if an only if this executable was declared
500 * to take a variable number of arguments.
501 */
502 public boolean isVarArgs() {
503 return (getModifiers() & Modifier.VARARGS) != 0;
504 }
505
506 /**
507 * Returns {@code true} if this executable is a synthetic
508 * construct; returns {@code false} otherwise.
509 *
510 * @return true if and only if this executable is a synthetic
511 * construct as defined by
512 * <cite>The Java™ Language Specification</cite>.
513 * @jls 13.1 The Form of a Binary
514 */
515 public boolean isSynthetic() {
516 return Modifier.isSynthetic(getModifiers());
517 }
518
519 /**
520 * Returns an array of arrays of {@code Annotation}s that
521 * represent the annotations on the formal parameters, in
522 * declaration order, of the {@code Executable} represented by
523 * this object. Synthetic and mandated parameters (see
524 * explanation below), such as the outer "this" parameter to an
525 * inner class constructor will be represented in the returned
526 * array. If the executable has no parameters (meaning no formal,
527 * no synthetic, and no mandated parameters), a zero-length array
528 * will be returned. If the {@code Executable} has one or more
529 * parameters, a nested array of length zero is returned for each
530 * parameter with no annotations. The annotation objects contained
531 * in the returned arrays are serializable. The caller of this
532 * method is free to modify the returned arrays; it will have no
533 * effect on the arrays returned to other callers.
534 *
535 * A compiler may add extra parameters that are implicitly
536 * declared in source ("mandated"), as well as parameters that
537 * are neither implicitly nor explicitly declared in source
538 * ("synthetic") to the parameter list for a method. See {@link
539 * java.lang.reflect.Parameter} for more information.
540 *
541 * @see java.lang.reflect.Parameter
542 * @see java.lang.reflect.Parameter#getAnnotations
543 * @return an array of arrays that represent the annotations on
544 * the formal and implicit parameters, in declaration order, of
545 * the executable represented by this object
546 */
547 public abstract Annotation[][] getParameterAnnotations();
548
549 Annotation[][] sharedGetParameterAnnotations(Class<?>[] parameterTypes,
550 byte[] parameterAnnotations) {
551 int numParameters = parameterTypes.length;
552 if (parameterAnnotations == null)
553 return new Annotation[numParameters][0];
554
555 Annotation[][] result = parseParameterAnnotations(parameterAnnotations);
556
557 if (result.length != numParameters)
558 handleParameterNumberMismatch(result.length, numParameters);
559 return result;
560 }
561
562 abstract void handleParameterNumberMismatch(int resultLength, int numParameters);
563
564 /**
565 * {@inheritDoc}
566 * @throws NullPointerException {@inheritDoc}
567 */
568 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
569 Objects.requireNonNull(annotationClass);
570 return annotationClass.cast(declaredAnnotations().get(annotationClass));
571 }
572
573 /**
574 * {@inheritDoc}
575 * @throws NullPointerException {@inheritDoc}
576 */
577 @Override
578 public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
579 Objects.requireNonNull(annotationClass);
580
581 return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass);
582 }
583
584 /**
585 * {@inheritDoc}
586 */
587 public Annotation[] getDeclaredAnnotations() {
588 return AnnotationParser.toArray(declaredAnnotations());
589 }
590
591 private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
592
593 private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
594 if (declaredAnnotations == null) {
595 Executable root = getRoot();
596 if (root != null) {
597 declaredAnnotations = root.declaredAnnotations();
598 } else {
599 declaredAnnotations = AnnotationParser.parseAnnotations(
600 getAnnotationBytes(),
601 sun.misc.SharedSecrets.getJavaLangAccess().
602 getConstantPool(getDeclaringClass()),
603 getDeclaringClass());
604 }
605 }
606 return declaredAnnotations;
607 }
608
609 /**
610 * Returns an {@code AnnotatedType} object that represents the use of a type to
611 * specify the return type of the method/constructor represented by this
612 * Executable.
613 *
614 * If this {@code Executable} object represents a constructor, the {@code
615 * AnnotatedType} object represents the type of the constructed object.
616 *
617 * If this {@code Executable} object represents a method, the {@code
618 * AnnotatedType} object represents the use of a type to specify the return
619 * type of the method.
620 *
621 * @return an object representing the return type of the method
622 * or constructor represented by this {@code Executable}
623 */
624 public abstract AnnotatedType getAnnotatedReturnType();
625
626 /* Helper for subclasses of Executable.
627 *
628 * Returns an AnnotatedType object that represents the use of a type to
629 * specify the return type of the method/constructor represented by this
630 * Executable.
631 */
632 AnnotatedType getAnnotatedReturnType0(Type returnType) {
633 return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
634 sun.misc.SharedSecrets.getJavaLangAccess().
635 getConstantPool(getDeclaringClass()),
636 this,
637 getDeclaringClass(),
638 returnType,
639 TypeAnnotation.TypeAnnotationTarget.METHOD_RETURN);
640 }
641
642 /**
643 * Returns an {@code AnnotatedType} object that represents the use of a
644 * type to specify the receiver type of the method/constructor represented
645 * by this Executable object. The receiver type of a method/constructor is
646 * available only if the method/constructor has a <em>receiver
647 * parameter</em> (JLS 8.4.1).
648 *
649 * If this {@code Executable} object represents a constructor or instance
650 * method that does not have a receiver parameter, or has a receiver
651 * parameter with no annotations on its type, then the return value is an
652 * {@code AnnotatedType} object representing an element with no
653 * annotations.
654 *
655 * If this {@code Executable} object represents a static method, then the
656 * return value is null.
657 *
658 * @return an object representing the receiver type of the method or
659 * constructor represented by this {@code Executable}
660 */
661 public AnnotatedType getAnnotatedReceiverType() {
662 if (Modifier.isStatic(this.getModifiers()))
663 return null;
664 return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
665 sun.misc.SharedSecrets.getJavaLangAccess().
666 getConstantPool(getDeclaringClass()),
667 this,
668 getDeclaringClass(),
669 getDeclaringClass(),
670 TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
671 }
672
673 /**
674 * Returns an array of {@code AnnotatedType} objects that represent the use
675 * of types to specify formal parameter types of the method/constructor
676 * represented by this Executable. The order of the objects in the array
677 * corresponds to the order of the formal parameter types in the
678 * declaration of the method/constructor.
679 *
680 * Returns an array of length 0 if the method/constructor declares no
681 * parameters.
682 *
683 * @return an array of objects representing the types of the
684 * formal parameters of the method or constructor represented by this
685 * {@code Executable}
686 */
687 public AnnotatedType[] getAnnotatedParameterTypes() {
688 return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
689 sun.misc.SharedSecrets.getJavaLangAccess().
690 getConstantPool(getDeclaringClass()),
691 this,
692 getDeclaringClass(),
693 getAllGenericParameterTypes(),
694 TypeAnnotation.TypeAnnotationTarget.METHOD_FORMAL_PARAMETER);
695 }
696
697 /**
698 * Returns an array of {@code AnnotatedType} objects that represent the use
699 * of types to specify the declared exceptions of the method/constructor
700 * represented by this Executable. The order of the objects in the array
701 * corresponds to the order of the exception types in the declaration of
702 * the method/constructor.
703 *
704 * Returns an array of length 0 if the method/constructor declares no
705 * exceptions.
706 *
707 * @return an array of objects representing the declared
708 * exceptions of the method or constructor represented by this {@code
709 * Executable}
710 */
711 public AnnotatedType[] getAnnotatedExceptionTypes() {
712 return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
713 sun.misc.SharedSecrets.getJavaLangAccess().
714 getConstantPool(getDeclaringClass()),
715 this,
716 getDeclaringClass(),
717 getGenericExceptionTypes(),
718 TypeAnnotation.TypeAnnotationTarget.THROWS);
719 }
720
721 }
722