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