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