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