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