--- old/src/share/classes/java/lang/reflect/Constructor.java 2011-07-11 21:45:29.000000000 -0700 +++ new/src/share/classes/java/lang/reflect/Constructor.java 2011-07-11 21:45:29.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,13 +27,12 @@ import sun.reflect.ConstructorAccessor; import sun.reflect.Reflection; +import sun.reflect.annotation.AnnotationParser; import sun.reflect.generics.repository.ConstructorRepository; import sun.reflect.generics.factory.CoreReflectionFactory; import sun.reflect.generics.factory.GenericsFactory; import sun.reflect.generics.scope.ConstructorScope; import java.lang.annotation.Annotation; -import java.util.Map; -import sun.reflect.annotation.AnnotationParser; import java.lang.annotation.AnnotationFormatError; import java.lang.reflect.Modifier; @@ -57,11 +56,7 @@ * @author Kenneth Russell * @author Nakul Saraiya */ -public final - class Constructor extends AccessibleObject implements - GenericDeclaration, - Member { - +public final class Constructor extends Executable { private Class clazz; private int slot; private Class[] parameterTypes; @@ -73,7 +68,7 @@ private transient ConstructorRepository genericInfo; private byte[] annotations; private byte[] parameterAnnotations; - + // Generics infrastructure // Accessor for factory private GenericsFactory getFactory() { @@ -111,8 +106,7 @@ int slot, String signature, byte[] annotations, - byte[] parameterAnnotations) - { + byte[] parameterAnnotations) { this.clazz = declaringClass; this.parameterTypes = parameterTypes; this.exceptionTypes = checkedExceptions; @@ -137,11 +131,11 @@ // objects be fabricated for each reflective call on Class // objects.) Constructor res = new Constructor<>(clazz, - parameterTypes, - exceptionTypes, modifiers, slot, - signature, - annotations, - parameterAnnotations); + parameterTypes, + exceptionTypes, modifiers, slot, + signature, + annotations, + parameterAnnotations); res.root = this; // Might as well eagerly propagate this if already present res.constructorAccessor = constructorAccessor; @@ -149,9 +143,9 @@ } /** - * Returns the {@code Class} object representing the class that declares - * the constructor represented by this {@code Constructor} object. + * {@inheritDoc} */ + @Override public Class getDeclaringClass() { return clazz; } @@ -160,36 +154,24 @@ * Returns the name of this constructor, as a string. This is * the binary name of the constructor's declaring class. */ + @Override public String getName() { return getDeclaringClass().getName(); } /** - * Returns the Java language modifiers for the constructor - * represented by this {@code Constructor} object, as an integer. The - * {@code Modifier} class should be used to decode the modifiers. - * - * @see Modifier + * {@inheritDoc} */ + @Override public int getModifiers() { return modifiers; } /** - * Returns an array of {@code TypeVariable} objects that represent the - * type variables declared by the generic declaration represented by this - * {@code GenericDeclaration} object, in declaration order. Returns an - * array of length 0 if the underlying generic declaration declares no type - * variables. - * - * @return an array of {@code TypeVariable} objects that represent - * the type variables declared by this generic declaration - * @throws GenericSignatureFormatError if the generic - * signature of this generic declaration does not conform to - * the format specified in - * The Java™ Virtual Machine Specification + * {@inheritDoc} * @since 1.5 */ + @Override public TypeVariable>[] getTypeParameters() { if (getSignature() != null) { return (TypeVariable>[])getGenericInfo().getTypeParameters(); @@ -199,46 +181,18 @@ /** - * Returns an array of {@code Class} objects that represent the formal - * parameter types, in declaration order, of the constructor - * represented by this {@code Constructor} object. Returns an array of - * length 0 if the underlying constructor takes no parameters. - * - * @return the parameter types for the constructor this object - * represents + * {@inheritDoc} */ + @Override public Class[] getParameterTypes() { return (Class[]) parameterTypes.clone(); } - /** - * Returns an array of {@code Type} objects that represent the formal - * parameter types, in declaration order, of the method represented by - * this {@code Constructor} object. Returns an array of length 0 if the - * underlying method takes no parameters. - * - *

If a formal parameter type is a parameterized type, - * the {@code Type} object returned for it must accurately reflect - * the actual type parameters used in the source code. - * - *

If a formal parameter type is a type variable or a parameterized - * type, it is created. Otherwise, it is resolved. - * - * @return an array of {@code Type}s that represent the formal - * parameter types of the underlying method, in declaration order - * @throws GenericSignatureFormatError - * if the generic method signature does not conform to the format - * specified in - * The Java™ Virtual Machine Specification - * @throws TypeNotPresentException if any of the parameter - * types of the underlying method refers to a non-existent type - * declaration - * @throws MalformedParameterizedTypeException if any of - * the underlying method's parameter types refer to a parameterized - * type that cannot be instantiated for any reason + * {@inheritDoc} * @since 1.5 */ + @Override public Type[] getGenericParameterTypes() { if (getSignature() != null) return getGenericInfo().getParameterTypes(); @@ -246,52 +200,30 @@ return getParameterTypes(); } - /** - * Returns an array of {@code Class} objects that represent the types - * of exceptions declared to be thrown by the underlying constructor - * represented by this {@code Constructor} object. Returns an array of - * length 0 if the constructor declares no exceptions in its {@code throws} clause. - * - * @return the exception types declared as being thrown by the - * constructor this object represents + * {@inheritDoc} + * @since 1.5 */ + @Override public Class[] getExceptionTypes() { return (Class[])exceptionTypes.clone(); } /** - * Returns an array of {@code Type} objects that represent the - * exceptions declared to be thrown by this {@code Constructor} object. - * Returns an array of length 0 if the underlying method declares - * no exceptions in its {@code throws} clause. - * - *

If an exception type is a type variable or a parameterized - * type, it is created. Otherwise, it is resolved. - * - * @return an array of Types that represent the exception types - * thrown by the underlying method - * @throws GenericSignatureFormatError - * if the generic method signature does not conform to the format - * specified in - * The Java™ Virtual Machine Specification - * @throws TypeNotPresentException if the underlying method's - * {@code throws} clause refers to a non-existent type declaration - * @throws MalformedParameterizedTypeException if - * the underlying method's {@code throws} clause refers to a - * parameterized type that cannot be instantiated for any reason + * {@inheritDoc} * @since 1.5 */ - public Type[] getGenericExceptionTypes() { - Type[] result; - if (getSignature() != null && - ( (result = getGenericInfo().getExceptionTypes()).length > 0 )) - return result; - else - return getExceptionTypes(); - } - + @Override + public Type[] getGenericExceptionTypes() { + Type[] result; + if (getSignature() != null && + ( (result = getGenericInfo().getExceptionTypes()).length > 0 )) + return result; + else + return getExceptionTypes(); + } + /** * Compares this {@code Constructor} against the specified object. * Returns true if the objects are the same. Two {@code Constructor} objects are @@ -302,16 +234,7 @@ if (obj != null && obj instanceof Constructor) { Constructor other = (Constructor)obj; if (getDeclaringClass() == other.getDeclaringClass()) { - /* Avoid unnecessary cloning */ - Class[] params1 = parameterTypes; - Class[] params2 = other.parameterTypes; - if (params1.length == params2.length) { - for (int i = 0; i < params1.length; i++) { - if (params1[i] != params2[i]) - return false; - } - return true; - } + return equalParamTypes(parameterTypes, other.parameterTypes); } } return false; @@ -343,28 +266,18 @@ */ public String toString() { try { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); int mod = getModifiers() & Modifier.constructorModifiers(); if (mod != 0) { sb.append(Modifier.toString(mod) + " "); } sb.append(Field.getTypeName(getDeclaringClass())); sb.append("("); - Class[] params = parameterTypes; // avoid clone - for (int j = 0; j < params.length; j++) { - sb.append(Field.getTypeName(params[j])); - if (j < (params.length - 1)) - sb.append(","); - } + separateWithCommas(parameterTypes, sb); sb.append(")"); - Class[] exceptions = exceptionTypes; // avoid clone - if (exceptions.length > 0) { + if (exceptionTypes.length > 0) { sb.append(" throws "); - for (int k = 0; k < exceptions.length; k++) { - sb.append(exceptions[k].getName()); - if (k < (exceptions.length - 1)) - sb.append(","); - } + separateWithCommas(exceptionTypes, sb); } return sb.toString(); } catch (Exception e) { @@ -405,6 +318,7 @@ * * @since 1.5 */ + @Override public String toGenericString() { try { StringBuilder sb = new StringBuilder(); @@ -526,29 +440,21 @@ } /** - * Returns {@code true} if this constructor was declared to take - * a variable number of arguments; returns {@code false} - * otherwise. - * - * @return {@code true} if an only if this constructor was declared to - * take a variable number of arguments. + * {@inheritDoc} * @since 1.5 */ + @Override public boolean isVarArgs() { - return (getModifiers() & Modifier.VARARGS) != 0; + return super.isVarArgs(); } /** - * Returns {@code true} if this constructor is a synthetic - * constructor; returns {@code false} otherwise. - * - * @return true if and only if this constructor is a synthetic - * constructor as defined by - * The Java™ Language Specification. + * {@inheritDoc} * @since 1.5 */ + @Override public boolean isSynthetic() { - return Modifier.isSynthetic(getModifiers()); + return super.isSynthetic(); } // NOTE that there is no synchronization used here. It is correct @@ -592,9 +498,9 @@ return slot; } - String getSignature() { - return signature; - } + String getSignature() { + return signature; + } byte[] getRawAnnotations() { return annotations; @@ -604,62 +510,19 @@ return parameterAnnotations; } - /** - * @throws NullPointerException {@inheritDoc} - * @since 1.5 - */ - public T getAnnotation(Class annotationClass) { - if (annotationClass == null) - throw new NullPointerException(); - - return (T) declaredAnnotations().get(annotationClass); - } /** + * {@inheritDoc} * @since 1.5 */ - public Annotation[] getDeclaredAnnotations() { - return AnnotationParser.toArray(declaredAnnotations()); - } - - private transient Map, Annotation> declaredAnnotations; - - private synchronized Map, Annotation> declaredAnnotations() { - if (declaredAnnotations == null) { - declaredAnnotations = AnnotationParser.parseAnnotations( - annotations, sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), - getDeclaringClass()); - } - return declaredAnnotations; - } - - /** - * Returns an array of arrays that represent the annotations on the formal - * parameters, in declaration order, of the method represented by - * this {@code Constructor} object. (Returns an array of length zero if the - * underlying method is parameterless. If the method has one or more - * parameters, a nested array of length zero is returned for each parameter - * with no annotations.) The annotation objects contained in the returned - * arrays are serializable. The caller of this method is free to modify - * the returned arrays; it will have no effect on the arrays returned to - * other callers. - * - * @return an array of arrays that represent the annotations on the formal - * parameters, in declaration order, of the method represented by this - * Constructor object - * @since 1.5 - */ + @Override public Annotation[][] getParameterAnnotations() { int numParameters = parameterTypes.length; if (parameterAnnotations == null) return new Annotation[numParameters][0]; - Annotation[][] result = AnnotationParser.parseParameterAnnotations( - parameterAnnotations, - sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), - getDeclaringClass()); + Annotation[][] result = parseParameterAnnotations(parameterAnnotations); + if (result.length != numParameters) { Class declaringClass = getDeclaringClass(); if (declaringClass.isEnum() || @@ -680,4 +543,9 @@ } return result; } + + @Override + byte[] getAnnotationBytes() { + return annotations; + } } --- old/src/share/classes/java/lang/reflect/Method.java 2011-07-11 21:45:30.000000000 -0700 +++ new/src/share/classes/java/lang/reflect/Method.java 2011-07-11 21:45:30.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,6 @@ import java.lang.annotation.Annotation; import java.lang.annotation.AnnotationFormatError; import java.nio.ByteBuffer; -import java.util.Map; /** * A {@code Method} provides information about, and access to, a single method @@ -58,9 +57,7 @@ * @author Kenneth Russell * @author Nakul Saraiya */ -public final - class Method extends AccessibleObject implements GenericDeclaration, - Member { +public final class Method extends Executable { private Class clazz; private int slot; // This is guaranteed to be interned by the VM in the 1.4 @@ -83,8 +80,8 @@ // potentially many Method objects pointing to it.) private Method root; - // Generics infrastructure + // Generics infrastructure private String getGenericSignature() {return signature;} // Accessor for factory @@ -119,8 +116,7 @@ String signature, byte[] annotations, byte[] parameterAnnotations, - byte[] annotationDefault) - { + byte[] annotationDefault) { this.clazz = declaringClass; this.name = name; this.parameterTypes = parameterTypes; @@ -155,11 +151,11 @@ res.methodAccessor = methodAccessor; return res; } - + /** - * Returns the {@code Class} object representing the class or interface - * that declares the method represented by this {@code Method} object. + * {@inheritDoc} */ + @Override public Class getDeclaringClass() { return clazz; } @@ -168,36 +164,24 @@ * Returns the name of the method represented by this {@code Method} * object, as a {@code String}. */ + @Override public String getName() { return name; } /** - * Returns the Java language modifiers for the method represented - * by this {@code Method} object, as an integer. The {@code Modifier} class should - * be used to decode the modifiers. - * - * @see Modifier + * {@inheritDoc} */ + @Override public int getModifiers() { return modifiers; } /** - * Returns an array of {@code TypeVariable} objects that represent the - * type variables declared by the generic declaration represented by this - * {@code GenericDeclaration} object, in declaration order. Returns an - * array of length 0 if the underlying generic declaration declares no type - * variables. - * - * @return an array of {@code TypeVariable} objects that represent - * the type variables declared by this generic declaration - * @throws GenericSignatureFormatError if the generic - * signature of this generic declaration does not conform to - * the format specified in - * The Java™ Virtual Machine Specification + * {@inheritDoc} * @since 1.5 */ + @Override public TypeVariable[] getTypeParameters() { if (getGenericSignature() != null) return (TypeVariable[])getGenericInfo().getTypeParameters(); @@ -245,47 +229,19 @@ } else { return getReturnType();} } - /** - * Returns an array of {@code Class} objects that represent the formal - * parameter types, in declaration order, of the method - * represented by this {@code Method} object. Returns an array of length - * 0 if the underlying method takes no parameters. - * - * @return the parameter types for the method this object - * represents + * {@inheritDoc} */ + @Override public Class[] getParameterTypes() { return (Class[]) parameterTypes.clone(); } /** - * Returns an array of {@code Type} objects that represent the formal - * parameter types, in declaration order, of the method represented by - * this {@code Method} object. Returns an array of length 0 if the - * underlying method takes no parameters. - * - *

If a formal parameter type is a parameterized type, - * the {@code Type} object returned for it must accurately reflect - * the actual type parameters used in the source code. - * - *

If a formal parameter type is a type variable or a parameterized - * type, it is created. Otherwise, it is resolved. - * - * @return an array of Types that represent the formal - * parameter types of the underlying method, in declaration order - * @throws GenericSignatureFormatError - * if the generic method signature does not conform to the format - * specified in - * The Java™ Virtual Machine Specification - * @throws TypeNotPresentException if any of the parameter - * types of the underlying method refers to a non-existent type - * declaration - * @throws MalformedParameterizedTypeException if any of - * the underlying method's parameter types refer to a parameterized - * type that cannot be instantiated for any reason + * {@inheritDoc} * @since 1.5 */ + @Override public Type[] getGenericParameterTypes() { if (getGenericSignature() != null) return getGenericInfo().getParameterTypes(); @@ -293,51 +249,28 @@ return getParameterTypes(); } - /** - * Returns an array of {@code Class} objects that represent - * the types of the exceptions declared to be thrown - * by the underlying method - * represented by this {@code Method} object. Returns an array of length - * 0 if the method declares no exceptions in its {@code throws} clause. - * - * @return the exception types declared as being thrown by the - * method this object represents + * {@inheritDoc} + * @since 1.5 */ + @Override public Class[] getExceptionTypes() { return (Class[]) exceptionTypes.clone(); } /** - * Returns an array of {@code Type} objects that represent the - * exceptions declared to be thrown by this {@code Method} object. - * Returns an array of length 0 if the underlying method declares - * no exceptions in its {@code throws} clause. - * - *

If an exception type is a type variable or a parameterized - * type, it is created. Otherwise, it is resolved. - * - * @return an array of Types that represent the exception types - * thrown by the underlying method - * @throws GenericSignatureFormatError - * if the generic method signature does not conform to the format - * specified in - * The Java™ Virtual Machine Specification - * @throws TypeNotPresentException if the underlying method's - * {@code throws} clause refers to a non-existent type declaration - * @throws MalformedParameterizedTypeException if - * the underlying method's {@code throws} clause refers to a - * parameterized type that cannot be instantiated for any reason + * {@inheritDoc} * @since 1.5 */ - public Type[] getGenericExceptionTypes() { - Type[] result; - if (getGenericSignature() != null && - ((result = getGenericInfo().getExceptionTypes()).length > 0)) - return result; - else - return getExceptionTypes(); - } + @Override + public Type[] getGenericExceptionTypes() { + Type[] result; + if (getGenericSignature() != null && + ((result = getGenericInfo().getExceptionTypes()).length > 0)) + return result; + else + return getExceptionTypes(); + } /** * Compares this {@code Method} against the specified object. Returns @@ -352,16 +285,7 @@ && (getName() == other.getName())) { if (!returnType.equals(other.getReturnType())) return false; - /* Avoid unnecessary cloning */ - Class[] params1 = parameterTypes; - Class[] params2 = other.parameterTypes; - if (params1.length == params2.length) { - for (int i = 0; i < params1.length; i++) { - if (params1[i] != params2[i]) - return false; - } - return true; - } + return equalParamTypes(parameterTypes, other.parameterTypes); } } return false; @@ -408,21 +332,11 @@ sb.append(Field.getTypeName(getReturnType())).append(' '); sb.append(Field.getTypeName(getDeclaringClass())).append('.'); sb.append(getName()).append('('); - Class[] params = parameterTypes; // avoid clone - for (int j = 0; j < params.length; j++) { - sb.append(Field.getTypeName(params[j])); - if (j < (params.length - 1)) - sb.append(','); - } + separateWithCommas(parameterTypes, sb); sb.append(')'); - Class[] exceptions = exceptionTypes; // avoid clone - if (exceptions.length > 0) { + if (exceptionTypes.length > 0) { sb.append(" throws "); - for (int k = 0; k < exceptions.length; k++) { - sb.append(exceptions[k].getName()); - if (k < (exceptions.length - 1)) - sb.append(','); - } + separateWithCommas(exceptionTypes, sb); } return sb.toString(); } catch (Exception e) { @@ -468,6 +382,7 @@ * * @since 1.5 */ + @Override public String toGenericString() { try { StringBuilder sb = new StringBuilder(); @@ -614,28 +529,21 @@ } /** - * Returns {@code true} if this method was declared to take - * a variable number of arguments; returns {@code false} - * otherwise. - * - * @return {@code true} if an only if this method was declared to - * take a variable number of arguments. + * {@inheritDoc} * @since 1.5 */ + @Override public boolean isVarArgs() { - return (getModifiers() & Modifier.VARARGS) != 0; + return super.isVarArgs(); } /** - * Returns {@code true} if this method is a synthetic - * method; returns {@code false} otherwise. - * - * @return true if and only if this method is a synthetic - * method as defined by the Java Language Specification. + * {@inheritDoc} * @since 1.5 */ + @Override public boolean isSynthetic() { - return Modifier.isSynthetic(getModifiers()); + return super.isSynthetic(); } // NOTE that there is no synchronization used here. It is correct @@ -675,36 +583,6 @@ } /** - * @throws NullPointerException {@inheritDoc} - * @since 1.5 - */ - public T getAnnotation(Class annotationClass) { - if (annotationClass == null) - throw new NullPointerException(); - - return (T) declaredAnnotations().get(annotationClass); - } - - /** - * @since 1.5 - */ - public Annotation[] getDeclaredAnnotations() { - return AnnotationParser.toArray(declaredAnnotations()); - } - - private transient Map, Annotation> declaredAnnotations; - - private synchronized Map, Annotation> declaredAnnotations() { - if (declaredAnnotations == null) { - declaredAnnotations = AnnotationParser.parseAnnotations( - annotations, sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), - getDeclaringClass()); - } - return declaredAnnotations; - } - - /** * Returns the default value for the annotation member represented by * this {@code Method} instance. If the member is of a primitive type, * an instance of the corresponding wrapper type is returned. Returns @@ -734,34 +612,26 @@ } /** - * Returns an array of arrays that represent the annotations on the formal - * parameters, in declaration order, of the method represented by - * this {@code Method} object. (Returns an array of length zero if the - * underlying method is parameterless. If the method has one or more - * parameters, a nested array of length zero is returned for each parameter - * with no annotations.) The annotation objects contained in the returned - * arrays are serializable. The caller of this method is free to modify - * the returned arrays; it will have no effect on the arrays returned to - * other callers. - * - * @return an array of arrays that represent the annotations on the formal - * parameters, in declaration order, of the method represented by this - * Method object + * {@inheritDoc} * @since 1.5 */ + @Override public Annotation[][] getParameterAnnotations() { int numParameters = parameterTypes.length; if (parameterAnnotations == null) return new Annotation[numParameters][0]; - Annotation[][] result = AnnotationParser.parseParameterAnnotations( - parameterAnnotations, - sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), - getDeclaringClass()); + Annotation[][] result = parseParameterAnnotations(parameterAnnotations); + if (result.length != numParameters) throw new java.lang.annotation.AnnotationFormatError( "Parameter annotations don't match number of parameters"); return result; } + + // TODO: move to other location in file + @Override + byte[] getAnnotationBytes() { + return annotations; + } } --- /dev/null 2011-07-10 02:18:37.148337923 -0700 +++ new/src/share/classes/java/lang/reflect/Executable.java 2011-07-11 21:45:30.000000000 -0700 @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.reflect; + +import java.lang.annotation.*; +import java.util.Map; +import sun.reflect.annotation.AnnotationParser; +import sun.reflect.generics.repository.ConstructorRepository; +import sun.reflect.generics.factory.CoreReflectionFactory; +import sun.reflect.generics.factory.GenericsFactory; +import sun.reflect.generics.scope.ConstructorScope; + +/** + * A shared superclass for the common functionality of {@link Method} + * and {@link Constructor}. + */ +public abstract class Executable extends AccessibleObject + implements Member, GenericDeclaration { + /* + * Accessor method to allow code sharing + */ + abstract byte[] getAnnotationBytes(); + + /* + * Only grant package-visibility to the constructor. + */ + Executable() {} + + boolean equalParamTypes(Class[] params1, Class[] params2) { + /* Avoid unnecessary cloning */ + if (params1.length == params2.length) { + for (int i = 0; i < params1.length; i++) { + if (params1[i] != params2[i]) + return false; + } + } + return true; + } + + Annotation[][] parseParameterAnnotations(byte[] parameterAnnotations) { + return AnnotationParser.parseParameterAnnotations( + parameterAnnotations, + sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + getDeclaringClass()); + } + + + void separateWithCommas(Class[] types, StringBuilder sb) { + for (int j = 0; j < types.length; j++) { + sb.append(Field.getTypeName(types[j])); + if (j < (types.length - 1)) + sb.append(","); + } + + } + + /** + * Returns the {@code Class} object representing the class or interface + * that declares the method represented by this Executable object. + */ + public abstract Class getDeclaringClass(); + + /** + * Returns the name of the executable represented by this object. + */ + public abstract String getName(); + + /** + * Returns the Java language {@linkplain Modifier modifiers} for + * the executable represented by this object. + */ + public abstract int getModifiers(); + + /** + * Returns an array of {@code TypeVariable} objects that represent the + * type variables declared by the generic declaration represented by this + * {@code GenericDeclaration} object, in declaration order. Returns an + * array of length 0 if the underlying generic declaration declares no type + * variables. + * + * @return an array of {@code TypeVariable} objects that represent + * the type variables declared by this generic declaration + * @throws GenericSignatureFormatError if the generic + * signature of this generic declaration does not conform to + * the format specified in + * The Java™ Virtual Machine Specification + */ + public abstract TypeVariable[] getTypeParameters(); + + /** + * Returns an array of {@code Class} objects that represent the formal + * parameter types, in declaration order, of the method + * represented by this {@code Method} object. Returns an array of length + * 0 if the underlying method takes no parameters. + * + * @return the parameter types for the method this object + * represents + */ + public abstract Class[] getParameterTypes(); + + /** + * Returns an array of {@code Type} objects that represent the formal + * parameter types, in declaration order, of the method represented by + * this executable object. Returns an array of length 0 if the + * underlying method takes no parameters. + * + *

If a formal parameter type is a parameterized type, + * the {@code Type} object returned for it must accurately reflect + * the actual type parameters used in the source code. + * + *

If a formal parameter type is a type variable or a parameterized + * type, it is created. Otherwise, it is resolved. + * + * @return an array of {@code Type}s that represent the formal + * parameter types of the underlying method, in declaration order + * @throws GenericSignatureFormatError + * if the generic method signature does not conform to the format + * specified in + * The Java™ Virtual Machine Specification + * @throws TypeNotPresentException if any of the parameter + * types of the underlying method refers to a non-existent type + * declaration + * @throws MalformedParameterizedTypeException if any of + * the underlying method's parameter types refer to a parameterized + * type that cannot be instantiated for any reason + */ + public abstract Type[] getGenericParameterTypes(); + + /** + * Returns an array of {@code Class} objects that represent the + * types of exceptions declared to be thrown by the underlying + * executable represented by this object. Returns an array of + * length 0 if the executable declares no exceptions in its {@code + * throws} clause. + * + * @return the exception types declared as being thrown by the + * executable this object represents + */ + public abstract Class[] getExceptionTypes(); + + /** + * Returns an array of {@code Type} objects that represent the + * exceptions declared to be thrown by this executable object. + * Returns an array of length 0 if the underlying executable declares + * no exceptions in its {@code throws} clause. + * + *

If an exception type is a type variable or a parameterized + * type, it is created. Otherwise, it is resolved. + * + * @return an array of Types that represent the exception types + * thrown by the underlying method + * @throws GenericSignatureFormatError + * if the generic method signature does not conform to the format + * specified in + * The Java™ Virtual Machine Specification + * @throws TypeNotPresentException if the underlying method's + * {@code throws} clause refers to a non-existent type declaration + * @throws MalformedParameterizedTypeException if + * the underlying method's {@code throws} clause refers to a + * parameterized type that cannot be instantiated for any reason + */ + public abstract Type[] getGenericExceptionTypes(); + + /** + * Returns a string describing this {@code Executable}, including + * any type parameters. + */ + public abstract String toGenericString(); + + /** + * Returns {@code true} if this executable was declared to take a + * variable number of arguments; returns {@code false} otherwise. + * + * @return {@code true} if an only if this executable was declared + * to take a variable number of arguments. + */ + public boolean isVarArgs() { + return (getModifiers() & Modifier.VARARGS) != 0; + } + + /** + * Returns {@code true} if this executable is a synthetic + * construct; returns {@code false} otherwise. + * + * @return true if and only if this executable is a synthetic + * construct as defined by + * The Java™ Language Specification. + */ + public boolean isSynthetic() { + return Modifier.isSynthetic(getModifiers()); + } + + /** + * Returns an array of arrays that represent the annotations on + * the formal parameters, in declaration order, of the executable + * represented by this object. (Returns an array of length zero if + * the underlying method is parameterless. If the executable has + * one or more parameters, a nested array of length zero is + * returned for each parameter with no annotations.) The + * annotation objects contained in the returned arrays are + * serializable. The caller of this method is free to modify the + * returned arrays; it will have no effect on the arrays returned + * to other callers. + * + * @return an array of arrays that represent the annotations on the formal + * parameters, in declaration order, of the exectuable represented by this + * object + */ + public abstract Annotation[][] getParameterAnnotations(); + + /** + * {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @since 1.5 + */ + public T getAnnotation(Class annotationClass) { + if (annotationClass == null) + throw new NullPointerException(); + + return (T) declaredAnnotations().get(annotationClass); + } + + /** + * {@inheritDoc} + * @since 1.5 + */ + public Annotation[] getDeclaredAnnotations() { + return AnnotationParser.toArray(declaredAnnotations()); + } + + private transient Map, Annotation> declaredAnnotations; + + private synchronized Map, Annotation> declaredAnnotations() { + if (declaredAnnotations == null) { + declaredAnnotations = AnnotationParser.parseAnnotations( + getAnnotationBytes(), + sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + getDeclaringClass()); + } + return declaredAnnotations; + } +}