1 /*
2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4  *
5  *
6  *
7  *
8  *
9  *
10  *
11  *
12  *
13  *
14  *
15  *
16  *
17  *
18  *
19  *
20  *
21  *
22  *
23  *
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      * Behaves like {@code getGenericParameterTypes}, but returns type
290      * information for all parameters, including synthetic parameters.
291      */

292     Type[] getAllGenericParameterTypes() {
293         final boolean genericInfo = hasGenericInformation();
294
295         // Easy case: we don't have generic parameter information.  In
296         // this case, we just return the result of
297         // getParameterTypes().
298         if (!genericInfo) {
299             return getParameterTypes();
300         } else {
301             final boolean realParamData = hasRealParameterData();
302             final Type[] genericParamTypes = getGenericParameterTypes();
303             final Type[] nonGenericParamTypes = getParameterTypes();
304             final Type[] out = new Type[nonGenericParamTypes.length];
305             final Parameter[] params = getParameters();
306             int fromidx = 0;
307             // If we have real parameter data, then we use the
308             // synthetic and mandate flags to our advantage.
309             if (realParamData) {
310                 for (int i = 0; i < out.length; i++) {
311                     final Parameter param = params[i];
312                     if (param.isSynthetic() || param.isImplicit()) {
313                         // If we hit a synthetic or mandated parameter,
314                         // use the non generic parameter info.
315                         out[i] = nonGenericParamTypes[i];
316                     } else {
317                         // Otherwise, use the generic parameter info.
318                         out[i] = genericParamTypes[fromidx];
319                         fromidx++;
320                     }
321                 }
322             } else {
323                 // Otherwise, use the non-generic parameter data.
324                 // Without method parameter reflection data, we have
325                 // no way to figure out which parameters are
326                 // synthetic/mandated, thus, no way to match up the
327                 // indexes.
328                 return genericParamTypes.length == nonGenericParamTypes.length ?
329                     genericParamTypes : nonGenericParamTypes;
330             }
331             return out;
332         }
333     }
334
335     /**
336      * Returns an array of {@code Parameter} objects that represent
337      * all the parameters to the underlying executable represented by
338      * this object.  Returns an array of length 0 if the executable
339      * has no parameters.
340      *
341      * <p>The parameters of the underlying executable do not necessarily
342      * have unique names, or names that are legal identifiers in the
343      * Java programming language (JLS 3.8).
344      *
345      * @throws MalformedParametersException if the class file contains
346      * a MethodParameters attribute that is improperly formatted.
347      * @return an array of {@code Parameter} objects representing all
348      * the parameters to the executable this object represents.
349      */

350     public Parameter[] getParameters() {
351         // TODO: This may eventually need to be guarded by security
352         // mechanisms similar to those in Field, Method, etc.
353         //
354         // Need to copy the cached array to prevent users from messing
355         // with it.  Since parameters are immutable, we can
356         // shallow-copy.
357         return privateGetParameters().clone();
358     }
359
360     private Parameter[] synthesizeAllParams() {
361         final int realparams = getParameterCount();
362         final Parameter[] out = new Parameter[realparams];
363         for (int i = 0; i < realparams; i++)
364             // TODO: is there a way to synthetically derive the
365             // modifiers?  Probably not in the general case, since
366             // we'd have no way of knowing about them, but there
367             // may be specific cases.
368             out[i] = new Parameter("arg" + i, 0, this, i);
369         return out;
370     }
371
372     private void verifyParameters(final Parameter[] parameters) {
373         final int mask = Modifier.FINAL | Modifier.SYNTHETIC | Modifier.MANDATED;
374
375         if (getParameterTypes().length != parameters.length)
376             throw new MalformedParametersException("Wrong number of parameters in MethodParameters attribute");
377
378         for (Parameter parameter : parameters) {
379             final String name = parameter.getRealName();
380             final int mods = parameter.getModifiers();
381
382             if (name != null) {
383                 if (name.isEmpty() || name.indexOf('.') != -1 ||
384                     name.indexOf(';') != -1 || name.indexOf('[') != -1 ||
385                     name.indexOf('/') != -1) {
386                     throw new MalformedParametersException("Invalid parameter name \"" + name + "\"");
387                 }
388             }
389
390             if (mods != (mods & mask)) {
391                 throw new MalformedParametersException("Invalid parameter modifiers");
392             }
393         }
394     }
395
396     private Parameter[] privateGetParameters() {
397         // Use tmp to avoid multiple writes to a volatile.
398         Parameter[] tmp = parameters;
399
400         if (tmp == null) {
401
402             // Otherwise, go to the JVM to get them
403             try {
404                 tmp = getParameters0();
405             } catch(IllegalArgumentException e) {
406                 // Rethrow ClassFormatErrors
407                 throw new MalformedParametersException("Invalid constant pool index");
408             }
409
410             // If we get back nothing, then synthesize parameters
411             if (tmp == null) {
412                 hasRealParameterData = false;
413                 tmp = synthesizeAllParams();
414             } else {
415                 hasRealParameterData = true;
416                 verifyParameters(tmp);
417             }
418
419             parameters = tmp;
420         }
421
422         return tmp;
423     }
424
425     boolean hasRealParameterData() {
426         // If this somehow gets called before parameters gets
427         // initialized, force it into existence.
428         if (parameters == null) {
429             privateGetParameters();
430         }
431         return hasRealParameterData;
432     }
433
434     private transient volatile boolean hasRealParameterData;
435     private transient volatile Parameter[] parameters;
436
437     private native Parameter[] getParameters0();
438     native byte[] getTypeAnnotationBytes0();
439
440     // Needed by reflectaccess
441     byte[] getTypeAnnotationBytes() {
442         return getTypeAnnotationBytes0();
443     }
444
445     /**
446      * Returns an array of {@code Class} objects that represent the
447      * types of exceptions declared to be thrown by the underlying
448      * executable represented by this object.  Returns an array of
449      * length 0 if the executable declares no exceptions in its {@code
450      * throws} clause.
451      *
452      * @return the exception types declared as being thrown by the
453      * executable this object represents
454      */

455     public abstract Class<?>[] getExceptionTypes();
456
457     /**
458      * Returns an array of {@code Type} objects that represent the
459      * exceptions declared to be thrown by this executable object.
460      * Returns an array of length 0 if the underlying executable declares
461      * no exceptions in its {@code throws} clause.
462      *
463      * <p>If an exception type is a type variable or a parameterized
464      * type, it is created. Otherwise, it is resolved.
465      *
466      * @return an array of Types that represent the exception types
467      *     thrown by the underlying executable
468      * @throws GenericSignatureFormatError
469      *     if the generic method signature does not conform to the format
470      *     specified in
471      *     <cite>The Java&trade; Virtual Machine Specification</cite>
472      * @throws TypeNotPresentException if the underlying executable's
473      *     {@code throws} clause refers to a non-existent type declaration
474      * @throws MalformedParameterizedTypeException if
475      *     the underlying executable's {@code throws} clause refers to a
476      *     parameterized type that cannot be instantiated for any reason
477      */

478     public Type[] getGenericExceptionTypes() {
479         Type[] result;
480         if (hasGenericInformation() &&
481             ((result = getGenericInfo().getExceptionTypes()).length > 0))
482             return result;
483         else
484             return getExceptionTypes();
485     }
486
487     /**
488      * Returns a string describing this {@code Executable}, including
489      * any type parameters.
490      * @return a string describing this {@code Executable}, including
491      * any type parameters
492      */

493     public abstract String toGenericString();
494
495     /**
496      * Returns {@code trueif this executable was declared to take a
497      * variable number of arguments; returns {@code false} otherwise.
498      *
499      * @return {@code trueif an only if this executable was declared
500      * to take a variable number of arguments.
501      */

502     public boolean isVarArgs()  {
503         return (getModifiers() & Modifier.VARARGS) != 0;
504     }
505
506     /**
507      * Returns {@code trueif this executable is a synthetic
508      * construct; returns {@code false} otherwise.
509      *
510      * @return true if and only if this executable is a synthetic
511      * construct as defined by
512      * <cite>The Java&trade; Language Specification</cite>.
513      * @jls 13.1 The Form of a Binary
514      */

515     public boolean isSynthetic() {
516         return Modifier.isSynthetic(getModifiers());
517     }
518
519     /**
520      * Returns an array of arrays of {@code Annotation}s that
521      * represent the annotations on the formal parameters, in
522      * declaration order, of the {@code Executable} represented by
523      * this object.  Synthetic and mandated parameters (see
524      * explanation below), such as the outer "this" parameter to an
525      * inner class constructor will be represented in the returned
526      * array.  If the executable has no parameters (meaning no formal,
527      * no synthetic, and no mandated parameters), a zero-length array
528      * will be returned.  If the {@code Executable} has one or more
529      * parameters, a nested array of length zero is returned for each
530      * parameter with no annotations. The annotation objects contained
531      * in the returned arrays are serializable.  The caller of this
532      * method is free to modify the returned arrays; it will have no
533      * effect on the arrays returned to other callers.
534      *
535      * A compiler may add extra parameters that are implicitly
536      * declared in source ("mandated"), as well as parameters that
537      * are neither implicitly nor explicitly declared in source
538      * ("synthetic") to the parameter list for a method.  See {@link
539      * java.lang.reflect.Parameter} for more information.
540      *
541      * @see java.lang.reflect.Parameter
542      * @see java.lang.reflect.Parameter#getAnnotations
543      * @return an array of arrays that represent the annotations on
544      *    the formal and implicit parameters, in declaration order, of
545      *    the executable represented by this object
546      */

547     public abstract Annotation[][] getParameterAnnotations();
548
549     Annotation[][] sharedGetParameterAnnotations(Class<?>[] parameterTypes,
550                                                  byte[] parameterAnnotations) {
551         int numParameters = parameterTypes.length;
552         if (parameterAnnotations == null)
553             return new Annotation[numParameters][0];
554
555         Annotation[][] result = parseParameterAnnotations(parameterAnnotations);
556
557         if (result.length != numParameters)
558             handleParameterNumberMismatch(result.length, numParameters);
559         return result;
560     }
561
562     abstract void handleParameterNumberMismatch(int resultLength, int numParameters);
563
564     /**
565      * {@inheritDoc}
566      * @throws NullPointerException  {@inheritDoc}
567      */

568     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
569         Objects.requireNonNull(annotationClass);
570         return annotationClass.cast(declaredAnnotations().get(annotationClass));
571     }
572
573     /**
574      * {@inheritDoc}
575      * @throws NullPointerException {@inheritDoc}
576      */

577     @Override
578     public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
579         Objects.requireNonNull(annotationClass);
580
581         return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass);
582     }
583
584     /**
585      * {@inheritDoc}
586      */

587     public Annotation[] getDeclaredAnnotations()  {
588         return AnnotationParser.toArray(declaredAnnotations());
589     }
590
591     private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
592
593     private synchronized  Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
594         if (declaredAnnotations == null) {
595             Executable root = getRoot();
596             if (root != null) {
597                 declaredAnnotations = root.declaredAnnotations();
598             } else {
599                 declaredAnnotations = AnnotationParser.parseAnnotations(
600                     getAnnotationBytes(),
601                     sun.misc.SharedSecrets.getJavaLangAccess().
602                     getConstantPool(getDeclaringClass()),
603                     getDeclaringClass());
604             }
605         }
606         return declaredAnnotations;
607     }
608
609     /**
610      * Returns an {@code AnnotatedType} object that represents the use of a type to
611      * specify the return type of the method/constructor represented by this
612      * Executable.
613      *
614      * If this {@code Executable} object represents a constructor, the {@code
615      * AnnotatedType} object represents the type of the constructed object.
616      *
617      * If this {@code Executable} object represents a method, the {@code
618      * AnnotatedType} object represents the use of a type to specify the return
619      * type of the method.
620      *
621      * @return an object representing the return type of the method
622      * or constructor represented by this {@code Executable}
623      */

624     public abstract AnnotatedType getAnnotatedReturnType();
625
626     /* Helper for subclasses of Executable.
627      *
628      * Returns an AnnotatedType object that represents the use of a type to
629      * specify the return type of the method/constructor represented by this
630      * Executable.
631      */

632     AnnotatedType getAnnotatedReturnType0(Type returnType) {
633         return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
634                 sun.misc.SharedSecrets.getJavaLangAccess().
635                         getConstantPool(getDeclaringClass()),
636                 this,
637                 getDeclaringClass(),
638                 returnType,
639                 TypeAnnotation.TypeAnnotationTarget.METHOD_RETURN);
640     }
641
642     /**
643      * Returns an {@code AnnotatedType} object that represents the use of a
644      * type to specify the receiver type of the method/constructor represented
645      * by this Executable object. The receiver type of a method/constructor is
646      * available only if the method/constructor has a <em>receiver
647      * parameter</em> (JLS 8.4.1).
648      *
649      * If this {@code Executable} object represents a constructor or instance
650      * method that does not have a receiver parameter, or has a receiver
651      * parameter with no annotations on its type, then the return value is an
652      * {@code AnnotatedType} object representing an element with no
653      * annotations.
654      *
655      * If this {@code Executable} object represents a static method, then the
656      * return value is null.
657      *
658      * @return an object representing the receiver type of the method or
659      * constructor represented by this {@code Executable}
660      */

661     public AnnotatedType getAnnotatedReceiverType() {
662         if (Modifier.isStatic(this.getModifiers()))
663             return null;
664         return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
665                 sun.misc.SharedSecrets.getJavaLangAccess().
666                         getConstantPool(getDeclaringClass()),
667                 this,
668                 getDeclaringClass(),
669                 getDeclaringClass(),
670                 TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
671     }
672
673     /**
674      * Returns an array of {@code AnnotatedType} objects that represent the use
675      * of types to specify formal parameter types of the method/constructor
676      * represented by this Executable. The order of the objects in the array
677      * corresponds to the order of the formal parameter types in the
678      * declaration of the method/constructor.
679      *
680      * Returns an array of length 0 if the method/constructor declares no
681      * parameters.
682      *
683      * @return an array of objects representing the types of the
684      * formal parameters of the method or constructor represented by this
685      * {@code Executable}
686      */

687     public AnnotatedType[] getAnnotatedParameterTypes() {
688         return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
689                 sun.misc.SharedSecrets.getJavaLangAccess().
690                         getConstantPool(getDeclaringClass()),
691                 this,
692                 getDeclaringClass(),
693                 getAllGenericParameterTypes(),
694                 TypeAnnotation.TypeAnnotationTarget.METHOD_FORMAL_PARAMETER);
695     }
696
697     /**
698      * Returns an array of {@code AnnotatedType} objects that represent the use
699      * of types to specify the declared exceptions of the method/constructor
700      * represented by this Executable. The order of the objects in the array
701      * corresponds to the order of the exception types in the declaration of
702      * the method/constructor.
703      *
704      * Returns an array of length 0 if the method/constructor declares no
705      * exceptions.
706      *
707      * @return an array of objects representing the declared
708      * exceptions of the method or constructor represented by this {@code
709      * Executable}
710      */

711     public AnnotatedType[] getAnnotatedExceptionTypes() {
712         return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
713                 sun.misc.SharedSecrets.getJavaLangAccess().
714                         getConstantPool(getDeclaringClass()),
715                 this,
716                 getDeclaringClass(),
717                 getGenericExceptionTypes(),
718                 TypeAnnotation.TypeAnnotationTarget.THROWS);
719     }
720
721 }
722
Powered by JavaMelody