rt/emul/mini/src/main/java/java/lang/reflect/Constructor.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 26 Feb 2013 16:54:16 +0100
changeset 772 d382dacfd73f
parent 604 emul/mini/src/main/java/java/lang/reflect/Constructor.java@3fcc279c921b
child 1321 7a78a84ab583
permissions -rw-r--r--
Moving modules around so the runtime is under one master pom and can be built without building other modules that are in the repository
     1 /*
     2  * Copyright (c) 1996, 2010, 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.Annotation;
    29 import org.apidesign.bck2brwsr.emul.reflect.TypeProvider;
    30 
    31 /**
    32  * {@code Constructor} provides information about, and access to, a single
    33  * constructor for a class.
    34  *
    35  * <p>{@code Constructor} permits widening conversions to occur when matching the
    36  * actual parameters to newInstance() with the underlying
    37  * constructor's formal parameters, but throws an
    38  * {@code IllegalArgumentException} if a narrowing conversion would occur.
    39  *
    40  * @param <T> the class in which the constructor is declared
    41  *
    42  * @see Member
    43  * @see java.lang.Class
    44  * @see java.lang.Class#getConstructors()
    45  * @see java.lang.Class#getConstructor(Class[])
    46  * @see java.lang.Class#getDeclaredConstructors()
    47  *
    48  * @author      Kenneth Russell
    49  * @author      Nakul Saraiya
    50  */
    51 public final
    52     class Constructor<T> extends AccessibleObject implements
    53                                                     GenericDeclaration,
    54                                                     Member {
    55 
    56     private Class<T>            clazz;
    57     private int                 slot;
    58     private Class<?>[]          parameterTypes;
    59     private Class<?>[]          exceptionTypes;
    60     private int                 modifiers;
    61     // Generics and annotations support
    62     private transient String    signature;
    63     private byte[]              annotations;
    64     private byte[]              parameterAnnotations;
    65 
    66 
    67     // For sharing of ConstructorAccessors. This branching structure
    68     // is currently only two levels deep (i.e., one root Constructor
    69     // and potentially many Constructor objects pointing to it.)
    70     private Constructor<T>      root;
    71 
    72     /**
    73      * Package-private constructor used by ReflectAccess to enable
    74      * instantiation of these objects in Java code from the java.lang
    75      * package via sun.reflect.LangReflectAccess.
    76      */
    77     Constructor(Class<T> declaringClass,
    78                 Class<?>[] parameterTypes,
    79                 Class<?>[] checkedExceptions,
    80                 int modifiers,
    81                 int slot,
    82                 String signature,
    83                 byte[] annotations,
    84                 byte[] parameterAnnotations)
    85     {
    86         this.clazz = declaringClass;
    87         this.parameterTypes = parameterTypes;
    88         this.exceptionTypes = checkedExceptions;
    89         this.modifiers = modifiers;
    90         this.slot = slot;
    91         this.signature = signature;
    92         this.annotations = annotations;
    93         this.parameterAnnotations = parameterAnnotations;
    94     }
    95 
    96     /**
    97      * Package-private routine (exposed to java.lang.Class via
    98      * ReflectAccess) which returns a copy of this Constructor. The copy's
    99      * "root" field points to this Constructor.
   100      */
   101     Constructor<T> copy() {
   102         return this;
   103     }
   104 
   105     /**
   106      * Returns the {@code Class} object representing the class that declares
   107      * the constructor represented by this {@code Constructor} object.
   108      */
   109     public Class<T> getDeclaringClass() {
   110         return clazz;
   111     }
   112 
   113     /**
   114      * Returns the name of this constructor, as a string.  This is
   115      * the binary name of the constructor's declaring class.
   116      */
   117     public String getName() {
   118         return getDeclaringClass().getName();
   119     }
   120 
   121     /**
   122      * Returns the Java language modifiers for the constructor
   123      * represented by this {@code Constructor} object, as an integer. The
   124      * {@code Modifier} class should be used to decode the modifiers.
   125      *
   126      * @see Modifier
   127      */
   128     public int getModifiers() {
   129         return modifiers;
   130     }
   131 
   132     /**
   133      * Returns an array of {@code TypeVariable} objects that represent the
   134      * type variables declared by the generic declaration represented by this
   135      * {@code GenericDeclaration} object, in declaration order.  Returns an
   136      * array of length 0 if the underlying generic declaration declares no type
   137      * variables.
   138      *
   139      * @return an array of {@code TypeVariable} objects that represent
   140      *     the type variables declared by this generic declaration
   141      * @throws GenericSignatureFormatError if the generic
   142      *     signature of this generic declaration does not conform to
   143      *     the format specified in
   144      *     <cite>The Java&trade; Virtual Machine Specification</cite>
   145      * @since 1.5
   146      */
   147     public TypeVariable<Constructor<T>>[] getTypeParameters() {
   148         return TypeProvider.getDefault().getTypeParameters(this);
   149     }
   150 
   151 
   152     /**
   153      * Returns an array of {@code Class} objects that represent the formal
   154      * parameter types, in declaration order, of the constructor
   155      * represented by this {@code Constructor} object.  Returns an array of
   156      * length 0 if the underlying constructor takes no parameters.
   157      *
   158      * @return the parameter types for the constructor this object
   159      * represents
   160      */
   161     public Class<?>[] getParameterTypes() {
   162         return (Class<?>[]) parameterTypes.clone();
   163     }
   164 
   165 
   166     /**
   167      * Returns an array of {@code Type} objects that represent the formal
   168      * parameter types, in declaration order, of the method represented by
   169      * this {@code Constructor} object. Returns an array of length 0 if the
   170      * underlying method takes no parameters.
   171      *
   172      * <p>If a formal parameter type is a parameterized type,
   173      * the {@code Type} object returned for it must accurately reflect
   174      * the actual type parameters used in the source code.
   175      *
   176      * <p>If a formal parameter type is a type variable or a parameterized
   177      * type, it is created. Otherwise, it is resolved.
   178      *
   179      * @return an array of {@code Type}s that represent the formal
   180      *     parameter types of the underlying method, in declaration order
   181      * @throws GenericSignatureFormatError
   182      *     if the generic method signature does not conform to the format
   183      *     specified in
   184      *     <cite>The Java&trade; Virtual Machine Specification</cite>
   185      * @throws TypeNotPresentException if any of the parameter
   186      *     types of the underlying method refers to a non-existent type
   187      *     declaration
   188      * @throws MalformedParameterizedTypeException if any of
   189      *     the underlying method's parameter types refer to a parameterized
   190      *     type that cannot be instantiated for any reason
   191      * @since 1.5
   192      */
   193     public Type[] getGenericParameterTypes() {
   194         return TypeProvider.getDefault().getGenericParameterTypes(this);
   195     }
   196 
   197 
   198     /**
   199      * Returns an array of {@code Class} objects that represent the types
   200      * of exceptions declared to be thrown by the underlying constructor
   201      * represented by this {@code Constructor} object.  Returns an array of
   202      * length 0 if the constructor declares no exceptions in its {@code throws} clause.
   203      *
   204      * @return the exception types declared as being thrown by the
   205      * constructor this object represents
   206      */
   207     public Class<?>[] getExceptionTypes() {
   208         return (Class<?>[])exceptionTypes.clone();
   209     }
   210 
   211 
   212     /**
   213      * Returns an array of {@code Type} objects that represent the
   214      * exceptions declared to be thrown by this {@code Constructor} object.
   215      * Returns an array of length 0 if the underlying method declares
   216      * no exceptions in its {@code throws} clause.
   217      *
   218      * <p>If an exception type is a type variable or a parameterized
   219      * type, it is created. Otherwise, it is resolved.
   220      *
   221      * @return an array of Types that represent the exception types
   222      *     thrown by the underlying method
   223      * @throws GenericSignatureFormatError
   224      *     if the generic method signature does not conform to the format
   225      *     specified in
   226      *     <cite>The Java&trade; Virtual Machine Specification</cite>
   227      * @throws TypeNotPresentException if the underlying method's
   228      *     {@code throws} clause refers to a non-existent type declaration
   229      * @throws MalformedParameterizedTypeException if
   230      *     the underlying method's {@code throws} clause refers to a
   231      *     parameterized type that cannot be instantiated for any reason
   232      * @since 1.5
   233      */
   234       public Type[] getGenericExceptionTypes() {
   235           return TypeProvider.getDefault().getGenericExceptionTypes(this);
   236       }
   237 
   238     /**
   239      * Compares this {@code Constructor} against the specified object.
   240      * Returns true if the objects are the same.  Two {@code Constructor} objects are
   241      * the same if they were declared by the same class and have the
   242      * same formal parameter types.
   243      */
   244     public boolean equals(Object obj) {
   245         if (obj != null && obj instanceof Constructor) {
   246             Constructor<?> other = (Constructor<?>)obj;
   247             if (getDeclaringClass() == other.getDeclaringClass()) {
   248                 /* Avoid unnecessary cloning */
   249                 Class<?>[] params1 = parameterTypes;
   250                 Class<?>[] params2 = other.parameterTypes;
   251                 if (params1.length == params2.length) {
   252                     for (int i = 0; i < params1.length; i++) {
   253                         if (params1[i] != params2[i])
   254                             return false;
   255                     }
   256                     return true;
   257                 }
   258             }
   259         }
   260         return false;
   261     }
   262 
   263     /**
   264      * Returns a hashcode for this {@code Constructor}. The hashcode is
   265      * the same as the hashcode for the underlying constructor's
   266      * declaring class name.
   267      */
   268     public int hashCode() {
   269         return getDeclaringClass().getName().hashCode();
   270     }
   271 
   272     /**
   273      * Returns a string describing this {@code Constructor}.  The string is
   274      * formatted as the constructor access modifiers, if any,
   275      * followed by the fully-qualified name of the declaring class,
   276      * followed by a parenthesized, comma-separated list of the
   277      * constructor's formal parameter types.  For example:
   278      * <pre>
   279      *    public java.util.Hashtable(int,float)
   280      * </pre>
   281      *
   282      * <p>The only possible modifiers for constructors are the access
   283      * modifiers {@code public}, {@code protected} or
   284      * {@code private}.  Only one of these may appear, or none if the
   285      * constructor has default (package) access.
   286      */
   287     public String toString() {
   288         try {
   289             StringBuffer sb = new StringBuffer();
   290             int mod = getModifiers() & Modifier.constructorModifiers();
   291             if (mod != 0) {
   292                 sb.append(Modifier.toString(mod) + " ");
   293             }
   294             sb.append(Field.getTypeName(getDeclaringClass()));
   295             sb.append("(");
   296             Class<?>[] params = parameterTypes; // avoid clone
   297             for (int j = 0; j < params.length; j++) {
   298                 sb.append(Field.getTypeName(params[j]));
   299                 if (j < (params.length - 1))
   300                     sb.append(",");
   301             }
   302             sb.append(")");
   303             Class<?>[] exceptions = exceptionTypes; // avoid clone
   304             if (exceptions.length > 0) {
   305                 sb.append(" throws ");
   306                 for (int k = 0; k < exceptions.length; k++) {
   307                     sb.append(exceptions[k].getName());
   308                     if (k < (exceptions.length - 1))
   309                         sb.append(",");
   310                 }
   311             }
   312             return sb.toString();
   313         } catch (Exception e) {
   314             return "<" + e + ">";
   315         }
   316     }
   317 
   318     /**
   319      * Returns a string describing this {@code Constructor},
   320      * including type parameters.  The string is formatted as the
   321      * constructor access modifiers, if any, followed by an
   322      * angle-bracketed comma separated list of the constructor's type
   323      * parameters, if any, followed by the fully-qualified name of the
   324      * declaring class, followed by a parenthesized, comma-separated
   325      * list of the constructor's generic formal parameter types.
   326      *
   327      * If this constructor was declared to take a variable number of
   328      * arguments, instead of denoting the last parameter as
   329      * "<tt><i>Type</i>[]</tt>", it is denoted as
   330      * "<tt><i>Type</i>...</tt>".
   331      *
   332      * A space is used to separate access modifiers from one another
   333      * and from the type parameters or return type.  If there are no
   334      * type parameters, the type parameter list is elided; if the type
   335      * parameter list is present, a space separates the list from the
   336      * class name.  If the constructor is declared to throw
   337      * exceptions, the parameter list is followed by a space, followed
   338      * by the word "{@code throws}" followed by a
   339      * comma-separated list of the thrown exception types.
   340      *
   341      * <p>The only possible modifiers for constructors are the access
   342      * modifiers {@code public}, {@code protected} or
   343      * {@code private}.  Only one of these may appear, or none if the
   344      * constructor has default (package) access.
   345      *
   346      * @return a string describing this {@code Constructor},
   347      * include type parameters
   348      *
   349      * @since 1.5
   350      */
   351     public String toGenericString() {
   352         try {
   353             StringBuilder sb = new StringBuilder();
   354             int mod = getModifiers() & Modifier.constructorModifiers();
   355             if (mod != 0) {
   356                 sb.append(Modifier.toString(mod) + " ");
   357             }
   358             TypeVariable<?>[] typeparms = getTypeParameters();
   359             if (typeparms.length > 0) {
   360                 boolean first = true;
   361                 sb.append("<");
   362                 for(TypeVariable<?> typeparm: typeparms) {
   363                     if (!first)
   364                         sb.append(",");
   365                     // Class objects can't occur here; no need to test
   366                     // and call Class.getName().
   367                     sb.append(typeparm.toString());
   368                     first = false;
   369                 }
   370                 sb.append("> ");
   371             }
   372             sb.append(Field.getTypeName(getDeclaringClass()));
   373             sb.append("(");
   374             Type[] params = getGenericParameterTypes();
   375             for (int j = 0; j < params.length; j++) {
   376                 String param = (params[j] instanceof Class<?>)?
   377                     Field.getTypeName((Class<?>)params[j]):
   378                     (params[j].toString());
   379                 if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
   380                     param = param.replaceFirst("\\[\\]$", "...");
   381                 sb.append(param);
   382                 if (j < (params.length - 1))
   383                     sb.append(",");
   384             }
   385             sb.append(")");
   386             Type[] exceptions = getGenericExceptionTypes();
   387             if (exceptions.length > 0) {
   388                 sb.append(" throws ");
   389                 for (int k = 0; k < exceptions.length; k++) {
   390                     sb.append((exceptions[k] instanceof Class)?
   391                               ((Class<?>)exceptions[k]).getName():
   392                               exceptions[k].toString());
   393                     if (k < (exceptions.length - 1))
   394                         sb.append(",");
   395                 }
   396             }
   397             return sb.toString();
   398         } catch (Exception e) {
   399             return "<" + e + ">";
   400         }
   401     }
   402 
   403     /**
   404      * Uses the constructor represented by this {@code Constructor} object to
   405      * create and initialize a new instance of the constructor's
   406      * declaring class, with the specified initialization parameters.
   407      * Individual parameters are automatically unwrapped to match
   408      * primitive formal parameters, and both primitive and reference
   409      * parameters are subject to method invocation conversions as necessary.
   410      *
   411      * <p>If the number of formal parameters required by the underlying constructor
   412      * is 0, the supplied {@code initargs} array may be of length 0 or null.
   413      *
   414      * <p>If the constructor's declaring class is an inner class in a
   415      * non-static context, the first argument to the constructor needs
   416      * to be the enclosing instance; see section 15.9.3 of
   417      * <cite>The Java&trade; Language Specification</cite>.
   418      *
   419      * <p>If the required access and argument checks succeed and the
   420      * instantiation will proceed, the constructor's declaring class
   421      * is initialized if it has not already been initialized.
   422      *
   423      * <p>If the constructor completes normally, returns the newly
   424      * created and initialized instance.
   425      *
   426      * @param initargs array of objects to be passed as arguments to
   427      * the constructor call; values of primitive types are wrapped in
   428      * a wrapper object of the appropriate type (e.g. a {@code float}
   429      * in a {@link java.lang.Float Float})
   430      *
   431      * @return a new object created by calling the constructor
   432      * this object represents
   433      *
   434      * @exception IllegalAccessException    if this {@code Constructor} object
   435      *              is enforcing Java language access control and the underlying
   436      *              constructor is inaccessible.
   437      * @exception IllegalArgumentException  if the number of actual
   438      *              and formal parameters differ; if an unwrapping
   439      *              conversion for primitive arguments fails; or if,
   440      *              after possible unwrapping, a parameter value
   441      *              cannot be converted to the corresponding formal
   442      *              parameter type by a method invocation conversion; if
   443      *              this constructor pertains to an enum type.
   444      * @exception InstantiationException    if the class that declares the
   445      *              underlying constructor represents an abstract class.
   446      * @exception InvocationTargetException if the underlying constructor
   447      *              throws an exception.
   448      * @exception ExceptionInInitializerError if the initialization provoked
   449      *              by this method fails.
   450      */
   451     public T newInstance(Object ... initargs)
   452         throws InstantiationException, IllegalAccessException,
   453                IllegalArgumentException, InvocationTargetException
   454     {
   455         throw new SecurityException();
   456     }
   457 
   458     /**
   459      * Returns {@code true} if this constructor was declared to take
   460      * a variable number of arguments; returns {@code false}
   461      * otherwise.
   462      *
   463      * @return {@code true} if an only if this constructor was declared to
   464      * take a variable number of arguments.
   465      * @since 1.5
   466      */
   467     public boolean isVarArgs() {
   468         return (getModifiers() & Modifier.VARARGS) != 0;
   469     }
   470 
   471     /**
   472      * Returns {@code true} if this constructor is a synthetic
   473      * constructor; returns {@code false} otherwise.
   474      *
   475      * @return true if and only if this constructor is a synthetic
   476      * constructor as defined by
   477      * <cite>The Java&trade; Language Specification</cite>.
   478      * @since 1.5
   479      */
   480     public boolean isSynthetic() {
   481         return Modifier.isSynthetic(getModifiers());
   482     }
   483 
   484     int getSlot() {
   485         return slot;
   486     }
   487 
   488    String getSignature() {
   489             return signature;
   490    }
   491 
   492     byte[] getRawAnnotations() {
   493         return annotations;
   494     }
   495 
   496     byte[] getRawParameterAnnotations() {
   497         return parameterAnnotations;
   498     }
   499 
   500     /**
   501      * @throws NullPointerException {@inheritDoc}
   502      * @since 1.5
   503      */
   504     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
   505         if (annotationClass == null)
   506             throw new NullPointerException();
   507 
   508         return null; // XXX (T) declaredAnnotations().get(annotationClass);
   509     }
   510 
   511     /**
   512      * @since 1.5
   513      */
   514     public Annotation[] getDeclaredAnnotations()  {
   515         return new Annotation[0]; // XXX AnnotationParser.toArray(declaredAnnotations());
   516     }
   517 
   518     /**
   519      * Returns an array of arrays that represent the annotations on the formal
   520      * parameters, in declaration order, of the method represented by
   521      * this {@code Constructor} object. (Returns an array of length zero if the
   522      * underlying method is parameterless.  If the method has one or more
   523      * parameters, a nested array of length zero is returned for each parameter
   524      * with no annotations.) The annotation objects contained in the returned
   525      * arrays are serializable.  The caller of this method is free to modify
   526      * the returned arrays; it will have no effect on the arrays returned to
   527      * other callers.
   528      *
   529      * @return an array of arrays that represent the annotations on the formal
   530      *    parameters, in declaration order, of the method represented by this
   531      *    Constructor object
   532      * @since 1.5
   533      */
   534     public Annotation[][] getParameterAnnotations() {
   535         int numParameters = parameterTypes.length;
   536         if (parameterAnnotations == null)
   537             return new Annotation[numParameters][0];
   538         
   539         return new Annotation[numParameters][0]; // XXX
   540 /*
   541         Annotation[][] result = AnnotationParser.parseParameterAnnotations(
   542             parameterAnnotations,
   543             sun.misc.SharedSecrets.getJavaLangAccess().
   544                 getConstantPool(getDeclaringClass()),
   545             getDeclaringClass());
   546         if (result.length != numParameters) {
   547             Class<?> declaringClass = getDeclaringClass();
   548             if (declaringClass.isEnum() ||
   549                 declaringClass.isAnonymousClass() ||
   550                 declaringClass.isLocalClass() )
   551                 ; // Can't do reliable parameter counting
   552             else {
   553                 if (!declaringClass.isMemberClass() || // top-level
   554                     // Check for the enclosing instance parameter for
   555                     // non-static member classes
   556                     (declaringClass.isMemberClass() &&
   557                      ((declaringClass.getModifiers() & Modifier.STATIC) == 0)  &&
   558                      result.length + 1 != numParameters) ) {
   559                     throw new AnnotationFormatError(
   560                               "Parameter annotations don't match number of parameters");
   561                 }
   562             }
   563         }
   564         return result;
   565         */
   566     }
   567 }