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