683 lines · 27.3 KB · Java
RawDownload
/* * Copyright (c) 1996, 2010, 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 sun.reflect.ConstructorAccessor;import sun.reflect.Reflection;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; /** * {@code Constructor} provides information about, and access to, a single * constructor for a class. * * <p>{@code Constructor} permits widening conversions to occur when matching the * actual parameters to newInstance() with the underlying * constructor's formal parameters, but throws an * {@code IllegalArgumentException} if a narrowing conversion would occur. * * @param <T> the class in which the constructor is declared * * @see Member * @see java.lang.Class * @see java.lang.Class#getConstructors() * @see java.lang.Class#getConstructor(Class[]) * @see java.lang.Class#getDeclaredConstructors() * * @author      Kenneth Russell * @author      Nakul Saraiya */public final    class Constructor<T> extends AccessibleObject implements                                                    GenericDeclaration,                                                    Member {     private Class<T>            clazz;    private int                 slot;    private Class<?>[]          parameterTypes;    private Class<?>[]          exceptionTypes;    private int                 modifiers;    // Generics and annotations support    private transient String    signature;    // generic info repository; lazily initialized    private transient ConstructorRepository genericInfo;    private byte[]              annotations;    private byte[]              parameterAnnotations;     // Generics infrastructure    // Accessor for factory    private GenericsFactory getFactory() {        // create scope and factory        return CoreReflectionFactory.make(this, ConstructorScope.make(this));    }     // Accessor for generic info repository    private ConstructorRepository getGenericInfo() {        // lazily initialize repository if necessary        if (genericInfo == null) {            // create and cache generic info repository            genericInfo =                ConstructorRepository.make(getSignature(),                                           getFactory());        }        return genericInfo; //return cached repository    }     private volatile ConstructorAccessor constructorAccessor;    // For sharing of ConstructorAccessors. This branching structure    // is currently only two levels deep (i.e., one root Constructor    // and potentially many Constructor objects pointing to it.)    private Constructor<T>      root;     /**     * Package-private constructor used by ReflectAccess to enable     * instantiation of these objects in Java code from the java.lang     * package via sun.reflect.LangReflectAccess.     */    Constructor(Class<T> declaringClass,                Class<?>[] parameterTypes,                Class<?>[] checkedExceptions,                int modifiers,                int slot,                String signature,                byte[] annotations,                byte[] parameterAnnotations)    {        this.clazz = declaringClass;        this.parameterTypes = parameterTypes;        this.exceptionTypes = checkedExceptions;        this.modifiers = modifiers;        this.slot = slot;        this.signature = signature;        this.annotations = annotations;        this.parameterAnnotations = parameterAnnotations;    }     /**     * Package-private routine (exposed to java.lang.Class via     * ReflectAccess) which returns a copy of this Constructor. The copy's     * "root" field points to this Constructor.     */    Constructor<T> copy() {        // This routine enables sharing of ConstructorAccessor objects        // among Constructor objects which refer to the same underlying        // method in the VM. (All of this contortion is only necessary        // because of the "accessibility" bit in AccessibleObject,        // which implicitly requires that new java.lang.reflect        // objects be fabricated for each reflective call on Class        // objects.)        Constructor<T> res = new Constructor<>(clazz,                                                parameterTypes,                                                exceptionTypes, modifiers, slot,                                                signature,                                                annotations,                                                parameterAnnotations);        res.root = this;        // Might as well eagerly propagate this if already present        res.constructorAccessor = constructorAccessor;        return res;    }     /**     * Returns the {@code Class} object representing the class that declares     * the constructor represented by this {@code Constructor} object.     */    public Class<T> getDeclaringClass() {        return clazz;    }     /**     * Returns the name of this constructor, as a string.  This is     * the binary name of the constructor's declaring class.     */    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     */    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     *     <cite>The Java&trade; Virtual Machine Specification</cite>     * @since 1.5     */    public TypeVariable<Constructor<T>>[] getTypeParameters() {      if (getSignature() != null) {        return (TypeVariable<Constructor<T>>[])getGenericInfo().getTypeParameters();      } else          return (TypeVariable<Constructor<T>>[])new TypeVariable[0];    }      /**     * 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     */    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.     *     * <p>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.     *     * <p>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     *     <cite>The Java&trade; Virtual Machine Specification</cite>     * @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     * @since 1.5     */    public Type[] getGenericParameterTypes() {        if (getSignature() != null)            return getGenericInfo().getParameterTypes();        else            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     */    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.     *     * <p>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     *     <cite>The Java&trade; Virtual Machine Specification</cite>     * @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     * @since 1.5     */      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     * the same if they were declared by the same class and have the     * same formal parameter types.     */    public boolean equals(Object obj) {        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 false;    }     /**     * Returns a hashcode for this {@code Constructor}. The hashcode is     * the same as the hashcode for the underlying constructor's     * declaring class name.     */    public int hashCode() {        return getDeclaringClass().getName().hashCode();    }     /**     * Returns a string describing this {@code Constructor}.  The string is     * formatted as the constructor access modifiers, if any,     * followed by the fully-qualified name of the declaring class,     * followed by a parenthesized, comma-separated list of the     * constructor's formal parameter types.  For example:     * <pre>     *    public java.util.Hashtable(int,float)     * </pre>     *     * <p>The only possible modifiers for constructors are the access     * modifiers {@code public}, {@code protected} or     * {@code private}.  Only one of these may appear, or none if the     * constructor has default (package) access.     */    public String toString() {        try {            StringBuffer sb = new StringBuffer();            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(",");            }            sb.append(")");            Class<?>[] exceptions = exceptionTypes; // avoid clone            if (exceptions.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(",");                }            }            return sb.toString();        } catch (Exception e) {            return "<" + e + ">";        }    }     /**     * Returns a string describing this {@code Constructor},     * including type parameters.  The string is formatted as the     * constructor access modifiers, if any, followed by an     * angle-bracketed comma separated list of the constructor's type     * parameters, if any, followed by the fully-qualified name of the     * declaring class, followed by a parenthesized, comma-separated     * list of the constructor's generic formal parameter types.     *     * If this constructor was declared to take a variable number of     * arguments, instead of denoting the last parameter as     * "<tt><i>Type</i>[]</tt>", it is denoted as     * "<tt><i>Type</i>...</tt>".     *     * A space is used to separate access modifiers from one another     * and from the type parameters or return type.  If there are no     * type parameters, the type parameter list is elided; if the type     * parameter list is present, a space separates the list from the     * class name.  If the constructor is declared to throw     * exceptions, the parameter list is followed by a space, followed     * by the word "{@code throws}" followed by a     * comma-separated list of the thrown exception types.     *     * <p>The only possible modifiers for constructors are the access     * modifiers {@code public}, {@code protected} or     * {@code private}.  Only one of these may appear, or none if the     * constructor has default (package) access.     *     * @return a string describing this {@code Constructor},     * include type parameters     *     * @since 1.5     */    public String toGenericString() {        try {            StringBuilder sb = new StringBuilder();            int mod = getModifiers() & Modifier.constructorModifiers();            if (mod != 0) {                sb.append(Modifier.toString(mod) + " ");            }            TypeVariable<?>[] typeparms = getTypeParameters();            if (typeparms.length > 0) {                boolean first = true;                sb.append("<");                for(TypeVariable<?> typeparm: typeparms) {                    if (!first)                        sb.append(",");                    // Class objects can't occur here; no need to test                    // and call Class.getName().                    sb.append(typeparm.toString());                    first = false;                }                sb.append("> ");            }            sb.append(Field.getTypeName(getDeclaringClass()));            sb.append("(");            Type[] params = getGenericParameterTypes();            for (int j = 0; j < params.length; j++) {                String param = (params[j] instanceof Class<?>)?                    Field.getTypeName((Class<?>)params[j]):                    (params[j].toString());                if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...                    param = param.replaceFirst("\\[\\]$", "...");                sb.append(param);                if (j < (params.length - 1))                    sb.append(",");            }            sb.append(")");            Type[] exceptions = getGenericExceptionTypes();            if (exceptions.length > 0) {                sb.append(" throws ");                for (int k = 0; k < exceptions.length; k++) {                    sb.append((exceptions[k] instanceof Class)?                              ((Class<?>)exceptions[k]).getName():                              exceptions[k].toString());                    if (k < (exceptions.length - 1))                        sb.append(",");                }            }            return sb.toString();        } catch (Exception e) {            return "<" + e + ">";        }    }     /**     * Uses the constructor represented by this {@code Constructor} object to     * create and initialize a new instance of the constructor's     * declaring class, with the specified initialization parameters.     * Individual parameters are automatically unwrapped to match     * primitive formal parameters, and both primitive and reference     * parameters are subject to method invocation conversions as necessary.     *     * <p>If the number of formal parameters required by the underlying constructor     * is 0, the supplied {@code initargs} array may be of length 0 or null.     *     * <p>If the constructor's declaring class is an inner class in a     * non-static context, the first argument to the constructor needs     * to be the enclosing instance; see section 15.9.3 of     * <cite>The Java&trade; Language Specification</cite>.     *     * <p>If the required access and argument checks succeed and the     * instantiation will proceed, the constructor's declaring class     * is initialized if it has not already been initialized.     *     * <p>If the constructor completes normally, returns the newly     * created and initialized instance.     *     * @param initargs array of objects to be passed as arguments to     * the constructor call; values of primitive types are wrapped in     * a wrapper object of the appropriate type (e.g. a {@code float}     * in a {@link java.lang.Float Float})     *     * @return a new object created by calling the constructor     * this object represents     *     * @exception IllegalAccessException    if this {@code Constructor} object     *              is enforcing Java language access control and the underlying     *              constructor is inaccessible.     * @exception IllegalArgumentException  if the number of actual     *              and formal parameters differ; if an unwrapping     *              conversion for primitive arguments fails; or if,     *              after possible unwrapping, a parameter value     *              cannot be converted to the corresponding formal     *              parameter type by a method invocation conversion; if     *              this constructor pertains to an enum type.

Lines 1–500 of 683.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t