1 /*
2 * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.reflect;
27
28 import java.lang.annotation.Annotation;
29 import java.util.Arrays;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.Objects;
33 import java.util.StringJoiner;
34 import java.util.stream.Collectors;
35
36 import jdk.internal.access.SharedSecrets;
37 import jdk.internal.vm.annotation.Stable;
38 import sun.reflect.annotation.AnnotationParser;
39 import sun.reflect.annotation.AnnotationSupport;
40 import sun.reflect.annotation.TypeAnnotationParser;
41 import sun.reflect.annotation.TypeAnnotation;
42 import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
43 import sun.reflect.generics.repository.ConstructorRepository;
44
45 /**
46 * A shared superclass for the common functionality of {@link Method}
47 * and {@link Constructor}.
48 *
49 * @sealedGraph
50 * @since 1.8
51 */
52 public abstract sealed class Executable extends AccessibleObject
53 implements Member, GenericDeclaration permits Constructor, Method {
54 /*
55 * Only grant package-visibility to the constructor.
56 */
57 @SuppressWarnings("deprecation")
58 Executable() {}
59
60 /**
61 * Accessor method to allow code sharing
62 */
63 abstract byte[] getAnnotationBytes();
64
65 /**
66 * Does the Executable have generic information.
67 */
68 abstract boolean hasGenericInformation();
69
70 abstract ConstructorRepository getGenericInfo();
71
72 boolean equalParamTypes(Class<?>[] params1, Class<?>[] params2) {
73 // The parameter arrays are trusted and the same for a root and all leaf
74 // copies. Thus, == on arrays is more useful than == on Executable.
75 if (params1 == params2)
76 return true;
77 /* Avoid unnecessary cloning */
78 if (params1.length == params2.length) {
79 for (int i = 0; i < params1.length; i++) {
80 if (params1[i] != params2[i])
81 return false;
82 }
83 return true;
84 }
85 return false;
86 }
87
88 Annotation[][] parseParameterAnnotations(byte[] parameterAnnotations) {
89 return AnnotationParser.parseParameterAnnotations(
90 parameterAnnotations,
91 SharedSecrets.getJavaLangAccess().
92 getConstantPool(getDeclaringClass()),
93 getDeclaringClass());
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 sb.append(Arrays.stream(parameterTypes)
123 .map(Type::getTypeName)
124 .collect(Collectors.joining(",", "(", ")")));
125 if (exceptionTypes.length > 0) {
126 sb.append(Arrays.stream(exceptionTypes)
127 .map(Type::getTypeName)
128 .collect(Collectors.joining(",", " throws ", "")));
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 static String typeVarBounds(TypeVariable<?> typeVar) {
143 Type[] bounds = typeVar.getBounds();
144 if (bounds.length == 1 && bounds[0].equals(Object.class)) {
145 return typeVar.getName();
146 } else {
147 return typeVar.getName() + " extends " +
148 Arrays.stream(bounds)
149 .map(Type::getTypeName)
150 .collect(Collectors.joining(" & "));
151 }
152 }
153
154 String sharedToGenericString(int modifierMask, boolean isDefault) {
155 try {
156 StringBuilder sb = new StringBuilder();
157
158 printModifiersIfNonzero(sb, modifierMask, isDefault);
159
160 TypeVariable<?>[] typeparms = getTypeParameters();
161 if (typeparms.length > 0) {
162 sb.append(Arrays.stream(typeparms)
163 .map(Executable::typeVarBounds)
164 .collect(Collectors.joining(",", "<", "> ")));
165 }
166
167 specificToGenericStringHeader(sb);
168
169 sb.append('(');
170 StringJoiner sj = new StringJoiner(",");
171 Type[] params = getGenericParameterTypes();
172 for (int j = 0; j < params.length; j++) {
173 String param = params[j].getTypeName();
174 if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
175 param = param.replaceFirst("\\[\\]$", "...");
176 sj.add(param);
177 }
178 sb.append(sj.toString());
179 sb.append(')');
180
181 Type[] exceptionTypes = getGenericExceptionTypes();
182 if (exceptionTypes.length > 0) {
183 sb.append(Arrays.stream(exceptionTypes)
184 .map(Type::getTypeName)
185 .collect(Collectors.joining(",", " throws ", "")));
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 * {@return the Java language {@linkplain Modifier modifiers} for
212 * the executable represented by this object}
213 * @see #accessFlags
214 */
215 public abstract int getModifiers();
216
217 /**
218 * {@return an unmodifiable set of the {@linkplain AccessFlag
219 * access flags} for the executable represented by this object,
220 * possibly empty}
221 * The {@code AccessFlags} may depend on the class file format version of the class.
222 *
223 * @see #getModifiers()
224 * @jvms 4.6 Methods
225 * @since 20
226 */
227 @Override
228 public Set<AccessFlag> accessFlags() {
229 return reflectionFactory.parseAccessFlags(getModifiers(),
230 AccessFlag.Location.METHOD,
231 getDeclaringClass());
232 }
233
234 /**
235 * Returns an array of {@code TypeVariable} objects that represent the
236 * type variables declared by the generic declaration represented by this
237 * {@code GenericDeclaration} object, in declaration order. Returns an
238 * array of length 0 if the underlying generic declaration declares no type
239 * variables.
240 *
241 * @return an array of {@code TypeVariable} objects that represent
242 * the type variables declared by this generic declaration
243 * @throws GenericSignatureFormatError if the generic
244 * signature of this generic declaration does not conform to
245 * the format specified in
246 * <cite>The Java Virtual Machine Specification</cite>
247 */
248 public abstract TypeVariable<?>[] getTypeParameters();
249
250 // returns shared array of parameter types - must never give it out
251 // to the untrusted code...
252 abstract Class<?>[] getSharedParameterTypes();
253
254 // returns shared array of exception types - must never give it out
255 // to the untrusted code...
256 abstract Class<?>[] getSharedExceptionTypes();
257
258 /**
259 * Returns an array of {@code Class} objects that represent the formal
260 * parameter types, in declaration order, of the executable
261 * represented by this object. Returns an array of length
262 * 0 if the underlying executable takes no parameters.
263 * Note that the constructors of some inner classes
264 * may have an {@linkplain java.compiler/javax.lang.model.util.Elements.Origin#MANDATED
265 * implicitly declared} parameter in addition to explicitly
266 * declared ones.
267 * Also note that compact constructors of a record class may have
268 * {@linkplain java.compiler/javax.lang.model.util.Elements.Origin#MANDATED
269 * implicitly declared} parameters.
270 *
271 * @return the parameter types for the executable this object
272 * represents
273 */
274 @SuppressWarnings("doclint:reference") // cross-module links
275 public abstract Class<?>[] getParameterTypes();
276
277 /**
278 * Returns the number of formal parameters (whether explicitly
279 * declared or implicitly declared or neither) for the executable
280 * represented by this object.
281 *
282 * @return The number of formal parameters for the executable this
283 * object represents
284 */
285 public abstract int getParameterCount();
286
287 /**
288 * Returns an array of {@code Type} objects that represent the
289 * formal parameter types, in declaration order, of the executable
290 * represented by this object. An array of length 0 is returned if the
291 * underlying executable takes no parameters. Note that the
292 * constructors of some inner classes may have an implicitly
293 * declared parameter in addition to explicitly declared ones.
294 * Compact constructors of a record class may also have
295 * {@linkplain java.compiler/javax.lang.model.util.Elements.Origin#MANDATED
296 * implicitly declared} parameters,
297 * but they are a special case and thus considered as if they had
298 * been explicitly declared in the source.
299 * Finally note that as a {@link java.lang.reflect##LanguageJvmModel
300 * modeling artifact}, the number of returned parameters can differ
301 * depending on whether or not generic information is present. If
302 * generic information is present, parameters explicitly
303 * present in the source or parameters of compact constructors
304 * of a record class will be returned.
305 * Note that parameters of compact constructors of a record class are a special case,
306 * as they are not explicitly present in the source, and its type will be returned
307 * regardless of the parameters being
308 * {@linkplain java.compiler/javax.lang.model.util.Elements.Origin#MANDATED
309 * implicitly declared} or not.
310 * If generic information is not present, implicit and synthetic parameters may be
311 * returned as well.
312 *
313 * <p>If a formal parameter type is a parameterized type,
314 * the {@code Type} object returned for it must accurately reflect
315 * the actual type arguments used in the source code. This assertion also
316 * applies to the parameters of compact constructors of a record class,
317 * independently of them being
318 * {@linkplain java.compiler/javax.lang.model.util.Elements.Origin#MANDATED
319 * implicitly declared} or not.
320 *
321 * <p>If a formal parameter type is a type variable or a parameterized
322 * type, it is created. Otherwise, it is resolved.
323 *
324 * @return an array of {@code Type}s that represent the formal
325 * parameter types of the underlying executable, in declaration order
326 * @throws GenericSignatureFormatError
327 * if the generic method signature does not conform to the format
328 * specified in
329 * <cite>The Java Virtual Machine Specification</cite>
330 * @throws TypeNotPresentException if any of the parameter
331 * types of the underlying executable refers to a non-existent type
332 * declaration
333 * @throws MalformedParameterizedTypeException if any of
334 * the underlying executable's parameter types refer to a parameterized
335 * type that cannot be instantiated for any reason
336 */
337 @SuppressWarnings("doclint:reference") // cross-module links
338 public Type[] getGenericParameterTypes() {
339 if (hasGenericInformation())
340 return getGenericInfo().getParameterTypes();
341 else
342 return getParameterTypes();
343 }
344
345 /**
346 * Behaves like {@code getGenericParameterTypes}, but returns type
347 * information for all parameters, including synthetic parameters.
348 */
349 Type[] getAllGenericParameterTypes() {
350 final boolean genericInfo = hasGenericInformation();
351
352 // Easy case: we don't have generic parameter information. In
353 // this case, we just return the result of
354 // getParameterTypes().
355 if (!genericInfo) {
356 return getParameterTypes();
357 } else {
358 final boolean realParamData = hasRealParameterData();
359 final Type[] genericParamTypes = getGenericParameterTypes();
360 final Type[] nonGenericParamTypes = getSharedParameterTypes();
361 // If we have real parameter data, then we use the
362 // synthetic and mandate flags to our advantage.
363 if (realParamData) {
364 if (getDeclaringClass().isRecord() && this instanceof Constructor) {
365 /* we could be seeing a compact constructor of a record class
366 * its parameters are mandated but we should be able to retrieve
367 * its generic information if present
368 */
369 if (genericParamTypes.length == nonGenericParamTypes.length) {
370 return genericParamTypes;
371 } else {
372 return nonGenericParamTypes.clone();
373 }
374 } else {
375 final Type[] out = new Type[nonGenericParamTypes.length];
376 final Parameter[] params = getParameters();
377 int fromidx = 0;
378 for (int i = 0; i < out.length; i++) {
379 final Parameter param = params[i];
380 if (param.isSynthetic() || param.isImplicit()) {
381 // If we hit a synthetic or mandated parameter,
382 // use the non generic parameter info.
383 out[i] = nonGenericParamTypes[i];
384 } else {
385 // Otherwise, use the generic parameter info.
386 out[i] = genericParamTypes[fromidx];
387 fromidx++;
388 }
389 }
390 return out;
391 }
392 } else {
393 // Otherwise, use the non-generic parameter data.
394 // Without method parameter reflection data, we have
395 // no way to figure out which parameters are
396 // synthetic/mandated, thus, no way to match up the
397 // indexes.
398 return genericParamTypes.length == nonGenericParamTypes.length ?
399 genericParamTypes : getParameterTypes();
400 }
401 }
402 }
403
404 /**
405 * {@return an array of {@code Parameter} objects representing
406 * all the parameters to the underlying executable represented by
407 * this object} An array of length 0 is returned if the executable
408 * has no parameters.
409 *
410 * <p>The parameters of the underlying executable do not necessarily
411 * have unique names, or names that are legal identifiers in the
412 * Java programming language (JLS {@jls 3.8}).
413 *
414 * @throws MalformedParametersException if the class file contains
415 * a MethodParameters attribute that is improperly formatted.
416 */
417 public Parameter[] getParameters() {
418 // TODO: This may eventually need to be guarded by security
419 // mechanisms similar to those in Field, Method, etc.
420 //
421 // Need to copy the cached array to prevent users from messing
422 // with it. Since parameters are immutable, we can
423 // shallow-copy.
424 return parameterData().parameters.clone();
425 }
426
427 private Parameter[] synthesizeAllParams() {
428 final int realparams = getParameterCount();
429 final Parameter[] out = new Parameter[realparams];
430 for (int i = 0; i < realparams; i++)
431 // TODO: is there a way to synthetically derive the
432 // modifiers? Probably not in the general case, since
433 // we'd have no way of knowing about them, but there
434 // may be specific cases.
435 out[i] = new Parameter(null, 0, this, i);
436 return out;
437 }
438
439 private void verifyParameters(final Parameter[] parameters) {
440 final int mask = Modifier.FINAL | Modifier.SYNTHETIC | Modifier.MANDATED;
441
442 if (getParameterCount() != parameters.length)
443 throw new MalformedParametersException("Wrong number of parameters in MethodParameters attribute");
444
445 for (Parameter parameter : parameters) {
446 final String name = parameter.getRealName();
447 final int mods = parameter.getModifiers();
448
449 if (name != null) {
450 if (name.isEmpty() || name.indexOf('.') != -1 ||
451 name.indexOf(';') != -1 || name.indexOf('[') != -1 ||
452 name.indexOf('/') != -1) {
453 throw new MalformedParametersException("Invalid parameter name \"" + name + "\"");
454 }
455 }
456
457 if (mods != (mods & mask)) {
458 throw new MalformedParametersException("Invalid parameter modifiers");
459 }
460 }
461 }
462
463
464 boolean hasRealParameterData() {
465 return parameterData().isReal;
466 }
467
468 private ParameterData parameterData() {
469 ParameterData parameterData = this.parameterData;
470 if (parameterData != null) {
471 return parameterData;
472 }
473
474 Parameter[] tmp;
475 // Go to the JVM to get them
476 try {
477 tmp = getParameters0();
478 } catch (IllegalArgumentException e) {
479 // Rethrow ClassFormatErrors
480 throw new MalformedParametersException("Invalid constant pool index");
481 }
482
483 // If we get back nothing, then synthesize parameters
484 if (tmp == null) {
485 tmp = synthesizeAllParams();
486 parameterData = new ParameterData(tmp, false);
487 } else {
488 verifyParameters(tmp);
489 parameterData = new ParameterData(tmp, true);
490 }
491 return this.parameterData = parameterData;
492 }
493
494 private transient @Stable ParameterData parameterData;
495
496 record ParameterData(@Stable Parameter[] parameters, boolean isReal) {}
497
498 private native Parameter[] getParameters0();
499 native byte[] getTypeAnnotationBytes0();
500
501 // Needed by reflectaccess
502 byte[] getTypeAnnotationBytes() {
503 return getTypeAnnotationBytes0();
504 }
505
506 /**
507 * Returns an array of {@code Class} objects that represent the
508 * types of exceptions declared to be thrown by the underlying
509 * executable represented by this object. Returns an array of
510 * length 0 if the executable declares no exceptions in its {@code
511 * throws} clause.
512 *
513 * @return the exception types declared as being thrown by the
514 * executable this object represents
515 */
516 public abstract Class<?>[] getExceptionTypes();
517
518 /**
519 * Returns an array of {@code Type} objects that represent the
520 * exceptions declared to be thrown by this executable object.
521 * Returns an array of length 0 if the underlying executable declares
522 * no exceptions in its {@code throws} clause.
523 *
524 * <p>If an exception type is a type variable or a parameterized
525 * type, it is created. Otherwise, it is resolved.
526 *
527 * @return an array of Types that represent the exception types
528 * thrown by the underlying executable
529 * @throws GenericSignatureFormatError
530 * if the generic method signature does not conform to the format
531 * specified in
532 * <cite>The Java Virtual Machine Specification</cite>
533 * @throws TypeNotPresentException if the underlying executable's
534 * {@code throws} clause refers to a non-existent type declaration
535 * @throws MalformedParameterizedTypeException if
536 * the underlying executable's {@code throws} clause refers to a
537 * parameterized type that cannot be instantiated for any reason
538 */
539 public Type[] getGenericExceptionTypes() {
540 Type[] result;
541 if (hasGenericInformation() &&
542 ((result = getGenericInfo().getExceptionTypes()).length > 0))
543 return result;
544 else
545 return getExceptionTypes();
546 }
547
548 /**
549 * {@return a string describing this {@code Executable}, including
550 * any type parameters}
551 */
552 public abstract String toGenericString();
553
554 /**
555 * {@return {@code true} if this executable was declared to take a
556 * variable number of arguments; returns {@code false} otherwise}
557 */
558 public boolean isVarArgs() {
559 return (getModifiers() & Modifier.VARARGS) != 0;
560 }
561
562 /**
563 * Returns {@code true} if this executable is a synthetic
564 * construct; returns {@code false} otherwise.
565 *
566 * @return true if and only if this executable is a synthetic
567 * construct as defined by
568 * <cite>The Java Language Specification</cite>.
569 * @jls 13.1 The Form of a Binary
570 * @jvms 4.6 Methods
571 */
572 public boolean isSynthetic() {
573 return Modifier.isSynthetic(getModifiers());
574 }
575
576 /**
577 * Returns an array of arrays of {@code Annotation}s that
578 * represent the annotations on the formal parameters, in
579 * declaration order, of the {@code Executable} represented by
580 * this object. Synthetic and mandated parameters (see
581 * explanation below), such as the outer "this" parameter to an
582 * inner class constructor will be represented in the returned
583 * array. If the executable has no parameters (meaning no formal,
584 * no synthetic, and no mandated parameters), a zero-length array
585 * will be returned. If the {@code Executable} has one or more
586 * parameters, a nested array of length zero is returned for each
587 * parameter with no annotations. The annotation objects contained
588 * in the returned arrays are serializable. The caller of this
589 * method is free to modify the returned arrays; it will have no
590 * effect on the arrays returned to other callers.
591 *
592 * A compiler may add extra parameters that are implicitly
593 * declared in source ("mandated"), as well as parameters that
594 * are neither implicitly nor explicitly declared in source
595 * ("synthetic") to the parameter list for a method. See {@link
596 * java.lang.reflect.Parameter} for more information.
597 *
598 * <p>Note that any annotations returned by this method are
599 * declaration annotations.
600 *
601 * @see java.lang.reflect.Parameter
602 * @see java.lang.reflect.Parameter#getAnnotations
603 * @return an array of arrays that represent the annotations on
604 * the formal and implicit parameters, in declaration order, of
605 * the executable represented by this object
606 */
607 public abstract Annotation[][] getParameterAnnotations();
608
609 Annotation[][] sharedGetParameterAnnotations(Class<?>[] parameterTypes,
610 byte[] parameterAnnotations) {
611 int numParameters = parameterTypes.length;
612 if (parameterAnnotations == null)
613 return new Annotation[numParameters][0];
614
615 Annotation[][] result = parseParameterAnnotations(parameterAnnotations);
616
617 if (result.length != numParameters &&
618 handleParameterNumberMismatch(result.length, parameterTypes)) {
619 Annotation[][] tmp = new Annotation[numParameters][];
620 // Shift annotations down to account for any implicit leading parameters
621 System.arraycopy(result, 0, tmp, numParameters - result.length, result.length);
622 for (int i = 0; i < numParameters - result.length; i++) {
623 tmp[i] = new Annotation[0];
624 }
625 result = tmp;
626 }
627 return result;
628 }
629
630 abstract boolean handleParameterNumberMismatch(int resultLength, Class<?>[] parameterTypes);
631
632 /**
633 * {@inheritDoc}
634 * @throws NullPointerException {@inheritDoc}
635 */
636 @Override
637 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
638 Objects.requireNonNull(annotationClass);
639 return annotationClass.cast(declaredAnnotations().get(annotationClass));
640 }
641
642 /**
643 * {@inheritDoc}
644 *
645 * @throws NullPointerException {@inheritDoc}
646 */
647 @Override
648 public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
649 Objects.requireNonNull(annotationClass);
650
651 return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass);
652 }
653
654 /**
655 * {@inheritDoc}
656 */
657 @Override
658 public Annotation[] getDeclaredAnnotations() {
659 return AnnotationParser.toArray(declaredAnnotations());
660 }
661
662 private transient volatile Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
663
664 private Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
665 Map<Class<? extends Annotation>, Annotation> declAnnos;
666 if ((declAnnos = declaredAnnotations) == null) {
667 synchronized (this) {
668 if ((declAnnos = declaredAnnotations) == null) {
669 Executable root = (Executable)getRoot();
670 if (root != null) {
671 declAnnos = root.declaredAnnotations();
672 } else {
673 declAnnos = AnnotationParser.parseAnnotations(
674 getAnnotationBytes(),
675 SharedSecrets.getJavaLangAccess().
676 getConstantPool(getDeclaringClass()),
677 getDeclaringClass()
678 );
679 }
680 declaredAnnotations = declAnnos;
681 }
682 }
683 }
684 return declAnnos;
685 }
686
687 /**
688 * Returns an {@code AnnotatedType} object that represents the use of a type to
689 * specify the return type of the method/constructor represented by this
690 * Executable.
691 *
692 * If this {@code Executable} object represents a constructor, the {@code
693 * AnnotatedType} object represents the type of the constructed object.
694 *
695 * If this {@code Executable} object represents a method, the {@code
696 * AnnotatedType} object represents the use of a type to specify the return
697 * type of the method.
698 *
699 * @return an object representing the return type of the method
700 * or constructor represented by this {@code Executable}
701 */
702 public abstract AnnotatedType getAnnotatedReturnType();
703
704 /* Helper for subclasses of Executable.
705 *
706 * Returns an AnnotatedType object that represents the use of a type to
707 * specify the return type of the method/constructor represented by this
708 * Executable.
709 */
710 AnnotatedType getAnnotatedReturnType0(Type returnType) {
711 return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
712 SharedSecrets.getJavaLangAccess().
713 getConstantPool(getDeclaringClass()),
714 this,
715 getDeclaringClass(),
716 returnType,
717 TypeAnnotation.TypeAnnotationTarget.METHOD_RETURN);
718 }
719
720 /**
721 * Returns an {@code AnnotatedType} object that represents the use of a
722 * type to specify the receiver type of the method/constructor represented
723 * by this {@code Executable} object.
724 *
725 * The receiver type of a method/constructor is available only if the
726 * method/constructor has a receiver parameter (JLS {@jls 8.4.1}). If this {@code
727 * Executable} object <em>represents an instance method or represents a
728 * constructor of an inner member class</em>, and the
729 * method/constructor <em>either</em> has no receiver parameter or has a
730 * receiver parameter with no annotations on its type, then the return
731 * value is an {@code AnnotatedType} object representing an element with no
732 * annotations.
733 *
734 * If this {@code Executable} object represents a static method or
735 * represents a constructor of a top level, static member, local, or
736 * anonymous class, then the return value is null.
737 *
738 * @return an object representing the receiver type of the method or
739 * constructor represented by this {@code Executable} or {@code null} if
740 * this {@code Executable} can not have a receiver parameter
741 *
742 * @jls 8.4 Method Declarations
743 * @jls 8.4.1 Formal Parameters
744 * @jls 8.8 Constructor Declarations
745 */
746 public AnnotatedType getAnnotatedReceiverType() {
747 if (Modifier.isStatic(this.getModifiers()))
748 return null;
749 return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
750 SharedSecrets.getJavaLangAccess().
751 getConstantPool(getDeclaringClass()),
752 this,
753 getDeclaringClass(),
754 parameterize(getDeclaringClass()),
755 TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
756 }
757
758 Type parameterize(Class<?> c) {
759 Class<?> ownerClass = c.getDeclaringClass();
760 TypeVariable<?>[] typeVars = c.getTypeParameters();
761
762 // base case, static nested classes, according to JLS 8.1.3, has no
763 // enclosing instance, therefore its owner is not generified.
764 if (ownerClass == null || Modifier.isStatic(c.getModifiers())) {
765 if (typeVars.length == 0)
766 return c;
767 else
768 return ParameterizedTypeImpl.make(c, typeVars, null);
769 }
770
771 // Resolve owner
772 Type ownerType = parameterize(ownerClass);
773 if (ownerType instanceof Class<?> && typeVars.length == 0) // We have yet to encounter type parameters
774 return c;
775 else
776 return ParameterizedTypeImpl.make(c, typeVars, ownerType);
777 }
778
779 /**
780 * Returns an array of {@code AnnotatedType} objects that represent the use
781 * of types to specify formal parameter types of the method/constructor
782 * represented by this Executable. The order of the objects in the array
783 * corresponds to the order of the formal parameter types in the
784 * declaration of the method/constructor.
785 *
786 * Returns an array of length 0 if the method/constructor declares no
787 * parameters.
788 * Note that the constructors of some inner classes
789 * may have an
790 * {@linkplain java.compiler/javax.lang.model.util.Elements.Origin#MANDATED
791 * implicitly declared} parameter in addition to explicitly declared ones.
792 * Also note that compact constructors of a record class may have
793 * {@linkplain java.compiler/javax.lang.model.util.Elements.Origin#MANDATED
794 * implicitly declared} parameters.
795 *
796 * @return an array of objects representing the types of the
797 * formal parameters of the method or constructor represented by this
798 * {@code Executable}
799 */
800 @SuppressWarnings("doclint:reference") // cross-module links
801 public AnnotatedType[] getAnnotatedParameterTypes() {
802 return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
803 SharedSecrets.getJavaLangAccess().
804 getConstantPool(getDeclaringClass()),
805 this,
806 getDeclaringClass(),
807 getAllGenericParameterTypes(),
808 TypeAnnotation.TypeAnnotationTarget.METHOD_FORMAL_PARAMETER);
809 }
810
811 /**
812 * Returns an array of {@code AnnotatedType} objects that represent the use
813 * of types to specify the declared exceptions of the method/constructor
814 * represented by this Executable. The order of the objects in the array
815 * corresponds to the order of the exception types in the declaration of
816 * the method/constructor.
817 *
818 * Returns an array of length 0 if the method/constructor declares no
819 * exceptions.
820 *
821 * @return an array of objects representing the declared
822 * exceptions of the method or constructor represented by this {@code
823 * Executable}
824 */
825 public AnnotatedType[] getAnnotatedExceptionTypes() {
826 return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
827 SharedSecrets.getJavaLangAccess().
828 getConstantPool(getDeclaringClass()),
829 this,
830 getDeclaringClass(),
831 getGenericExceptionTypes(),
832 TypeAnnotation.TypeAnnotationTarget.THROWS);
833 }
834 }