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.
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.
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).
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.
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
26 package java.lang.reflect;
28 import java.lang.annotation.Annotation;
29 import static java.lang.reflect.Method.fromPrimitive;
30 import static java.lang.reflect.Method.getAccess;
31 import static java.lang.reflect.Method.getParameterTypes;
32 import org.apidesign.bck2brwsr.core.JavaScriptBody;
33 import org.apidesign.bck2brwsr.emul.reflect.TypeProvider;
36 * {@code Constructor} provides information about, and access to, a single
37 * constructor for a class.
39 * <p>{@code Constructor} permits widening conversions to occur when matching the
40 * actual parameters to newInstance() with the underlying
41 * constructor's formal parameters, but throws an
42 * {@code IllegalArgumentException} if a narrowing conversion would occur.
44 * @param <T> the class in which the constructor is declared
47 * @see java.lang.Class
48 * @see java.lang.Class#getConstructors()
49 * @see java.lang.Class#getConstructor(Class[])
50 * @see java.lang.Class#getDeclaredConstructors()
52 * @author Kenneth Russell
53 * @author Nakul Saraiya
56 class Constructor<T> extends AccessibleObject implements
60 private final Class<T> clazz;
61 private final Object data;
62 private final String sig;
65 * Package-private constructor used by ReflectAccess to enable
66 * instantiation of these objects in Java code from the java.lang
67 * package via sun.reflect.LangReflectAccess.
69 Constructor(Class<T> declaringClass, Object data, String sig)
71 this.clazz = declaringClass;
77 * Package-private routine (exposed to java.lang.Class via
78 * ReflectAccess) which returns a copy of this Constructor. The copy's
79 * "root" field points to this Constructor.
81 Constructor<T> copy() {
86 * Returns the {@code Class} object representing the class that declares
87 * the constructor represented by this {@code Constructor} object.
89 public Class<T> getDeclaringClass() {
94 * Returns the name of this constructor, as a string. This is
95 * the binary name of the constructor's declaring class.
97 public String getName() {
98 return getDeclaringClass().getName();
102 * Returns the Java language modifiers for the constructor
103 * represented by this {@code Constructor} object, as an integer. The
104 * {@code Modifier} class should be used to decode the modifiers.
108 public int getModifiers() {
109 return getAccess(data);
113 * Returns an array of {@code TypeVariable} objects that represent the
114 * type variables declared by the generic declaration represented by this
115 * {@code GenericDeclaration} object, in declaration order. Returns an
116 * array of length 0 if the underlying generic declaration declares no type
119 * @return an array of {@code TypeVariable} objects that represent
120 * the type variables declared by this generic declaration
121 * @throws GenericSignatureFormatError if the generic
122 * signature of this generic declaration does not conform to
123 * the format specified in
124 * <cite>The Java™ Virtual Machine Specification</cite>
127 public TypeVariable<Constructor<T>>[] getTypeParameters() {
128 return TypeProvider.getDefault().getTypeParameters(this);
133 * Returns an array of {@code Class} objects that represent the formal
134 * parameter types, in declaration order, of the constructor
135 * represented by this {@code Constructor} object. Returns an array of
136 * length 0 if the underlying constructor takes no parameters.
138 * @return the parameter types for the constructor this object
141 public Class<?>[] getParameterTypes() {
142 return Method.getParameterTypes(sig);
147 * Returns an array of {@code Type} objects that represent the formal
148 * parameter types, in declaration order, of the method represented by
149 * this {@code Constructor} object. Returns an array of length 0 if the
150 * underlying method takes no parameters.
152 * <p>If a formal parameter type is a parameterized type,
153 * the {@code Type} object returned for it must accurately reflect
154 * the actual type parameters used in the source code.
156 * <p>If a formal parameter type is a type variable or a parameterized
157 * type, it is created. Otherwise, it is resolved.
159 * @return an array of {@code Type}s that represent the formal
160 * parameter types of the underlying method, in declaration order
161 * @throws GenericSignatureFormatError
162 * if the generic method signature does not conform to the format
164 * <cite>The Java™ Virtual Machine Specification</cite>
165 * @throws TypeNotPresentException if any of the parameter
166 * types of the underlying method refers to a non-existent type
168 * @throws MalformedParameterizedTypeException if any of
169 * the underlying method's parameter types refer to a parameterized
170 * type that cannot be instantiated for any reason
173 public Type[] getGenericParameterTypes() {
174 return TypeProvider.getDefault().getGenericParameterTypes(this);
179 * Returns an array of {@code Class} objects that represent the types
180 * of exceptions declared to be thrown by the underlying constructor
181 * represented by this {@code Constructor} object. Returns an array of
182 * length 0 if the constructor declares no exceptions in its {@code throws} clause.
184 * @return the exception types declared as being thrown by the
185 * constructor this object represents
187 public Class<?>[] getExceptionTypes() {
188 throw new UnsupportedOperationException();
193 * Returns an array of {@code Type} objects that represent the
194 * exceptions declared to be thrown by this {@code Constructor} object.
195 * Returns an array of length 0 if the underlying method declares
196 * no exceptions in its {@code throws} clause.
198 * <p>If an exception type is a type variable or a parameterized
199 * type, it is created. Otherwise, it is resolved.
201 * @return an array of Types that represent the exception types
202 * thrown by the underlying method
203 * @throws GenericSignatureFormatError
204 * if the generic method signature does not conform to the format
206 * <cite>The Java™ Virtual Machine Specification</cite>
207 * @throws TypeNotPresentException if the underlying method's
208 * {@code throws} clause refers to a non-existent type declaration
209 * @throws MalformedParameterizedTypeException if
210 * the underlying method's {@code throws} clause refers to a
211 * parameterized type that cannot be instantiated for any reason
214 public Type[] getGenericExceptionTypes() {
215 return TypeProvider.getDefault().getGenericExceptionTypes(this);
219 * Compares this {@code Constructor} against the specified object.
220 * Returns true if the objects are the same. Two {@code Constructor} objects are
221 * the same if they were declared by the same class and have the
222 * same formal parameter types.
224 public boolean equals(Object obj) {
225 if (obj instanceof Constructor) {
226 Constructor other = (Constructor)obj;
227 return data == other.data;
233 * Returns a hashcode for this {@code Constructor}. The hashcode is
234 * the same as the hashcode for the underlying constructor's
235 * declaring class name.
237 public int hashCode() {
238 return getDeclaringClass().getName().hashCode();
242 * Returns a string describing this {@code Constructor}. The string is
243 * formatted as the constructor access modifiers, if any,
244 * followed by the fully-qualified name of the declaring class,
245 * followed by a parenthesized, comma-separated list of the
246 * constructor's formal parameter types. For example:
248 * public java.util.Hashtable(int,float)
251 * <p>The only possible modifiers for constructors are the access
252 * modifiers {@code public}, {@code protected} or
253 * {@code private}. Only one of these may appear, or none if the
254 * constructor has default (package) access.
256 public String toString() {
258 StringBuffer sb = new StringBuffer();
259 int mod = getModifiers() & Modifier.constructorModifiers();
261 sb.append(Modifier.toString(mod) + " ");
263 sb.append(Field.getTypeName(getDeclaringClass()));
265 Class<?>[] params = getParameterTypes(); // avoid clone
266 for (int j = 0; j < params.length; j++) {
267 sb.append(Field.getTypeName(params[j]));
268 if (j < (params.length - 1))
273 Class<?>[] exceptions = exceptionTypes; // avoid clone
274 if (exceptions.length > 0) {
275 sb.append(" throws ");
276 for (int k = 0; k < exceptions.length; k++) {
277 sb.append(exceptions[k].getName());
278 if (k < (exceptions.length - 1))
283 return sb.toString();
284 } catch (Exception e) {
285 return "<" + e + ">";
290 * Returns a string describing this {@code Constructor},
291 * including type parameters. The string is formatted as the
292 * constructor access modifiers, if any, followed by an
293 * angle-bracketed comma separated list of the constructor's type
294 * parameters, if any, followed by the fully-qualified name of the
295 * declaring class, followed by a parenthesized, comma-separated
296 * list of the constructor's generic formal parameter types.
298 * If this constructor was declared to take a variable number of
299 * arguments, instead of denoting the last parameter as
300 * "<tt><i>Type</i>[]</tt>", it is denoted as
301 * "<tt><i>Type</i>...</tt>".
303 * A space is used to separate access modifiers from one another
304 * and from the type parameters or return type. If there are no
305 * type parameters, the type parameter list is elided; if the type
306 * parameter list is present, a space separates the list from the
307 * class name. If the constructor is declared to throw
308 * exceptions, the parameter list is followed by a space, followed
309 * by the word "{@code throws}" followed by a
310 * comma-separated list of the thrown exception types.
312 * <p>The only possible modifiers for constructors are the access
313 * modifiers {@code public}, {@code protected} or
314 * {@code private}. Only one of these may appear, or none if the
315 * constructor has default (package) access.
317 * @return a string describing this {@code Constructor},
318 * include type parameters
322 public String toGenericString() {
324 StringBuilder sb = new StringBuilder();
325 int mod = getModifiers() & Modifier.constructorModifiers();
327 sb.append(Modifier.toString(mod) + " ");
329 TypeVariable<?>[] typeparms = getTypeParameters();
330 if (typeparms.length > 0) {
331 boolean first = true;
333 for(TypeVariable<?> typeparm: typeparms) {
336 // Class objects can't occur here; no need to test
337 // and call Class.getName().
338 sb.append(typeparm.toString());
343 sb.append(Field.getTypeName(getDeclaringClass()));
345 Type[] params = getGenericParameterTypes();
346 for (int j = 0; j < params.length; j++) {
347 String param = (params[j] instanceof Class<?>)?
348 Field.getTypeName((Class<?>)params[j]):
349 (params[j].toString());
350 if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
351 param = param.replaceFirst("\\[\\]$", "...");
353 if (j < (params.length - 1))
357 Type[] exceptions = getGenericExceptionTypes();
358 if (exceptions.length > 0) {
359 sb.append(" throws ");
360 for (int k = 0; k < exceptions.length; k++) {
361 sb.append((exceptions[k] instanceof Class)?
362 ((Class<?>)exceptions[k]).getName():
363 exceptions[k].toString());
364 if (k < (exceptions.length - 1))
368 return sb.toString();
369 } catch (Exception e) {
370 return "<" + e + ">";
375 * Uses the constructor represented by this {@code Constructor} object to
376 * create and initialize a new instance of the constructor's
377 * declaring class, with the specified initialization parameters.
378 * Individual parameters are automatically unwrapped to match
379 * primitive formal parameters, and both primitive and reference
380 * parameters are subject to method invocation conversions as necessary.
382 * <p>If the number of formal parameters required by the underlying constructor
383 * is 0, the supplied {@code initargs} array may be of length 0 or null.
385 * <p>If the constructor's declaring class is an inner class in a
386 * non-static context, the first argument to the constructor needs
387 * to be the enclosing instance; see section 15.9.3 of
388 * <cite>The Java™ Language Specification</cite>.
390 * <p>If the required access and argument checks succeed and the
391 * instantiation will proceed, the constructor's declaring class
392 * is initialized if it has not already been initialized.
394 * <p>If the constructor completes normally, returns the newly
395 * created and initialized instance.
397 * @param initargs array of objects to be passed as arguments to
398 * the constructor call; values of primitive types are wrapped in
399 * a wrapper object of the appropriate type (e.g. a {@code float}
400 * in a {@link java.lang.Float Float})
402 * @return a new object created by calling the constructor
403 * this object represents
405 * @exception IllegalAccessException if this {@code Constructor} object
406 * is enforcing Java language access control and the underlying
407 * constructor is inaccessible.
408 * @exception IllegalArgumentException if the number of actual
409 * and formal parameters differ; if an unwrapping
410 * conversion for primitive arguments fails; or if,
411 * after possible unwrapping, a parameter value
412 * cannot be converted to the corresponding formal
413 * parameter type by a method invocation conversion; if
414 * this constructor pertains to an enum type.
415 * @exception InstantiationException if the class that declares the
416 * underlying constructor represents an abstract class.
417 * @exception InvocationTargetException if the underlying constructor
418 * throws an exception.
419 * @exception ExceptionInInitializerError if the initialization provoked
420 * by this method fails.
422 public T newInstance(Object ... initargs)
423 throws InstantiationException, IllegalAccessException,
424 IllegalArgumentException, InvocationTargetException
426 Class[] types = getParameterTypes();
427 if (types.length != initargs.length) {
428 throw new IllegalArgumentException("Types len " + types.length + " args: " + initargs.length);
430 initargs = initargs.clone();
431 for (int i = 0; i < types.length; i++) {
433 if (c.isPrimitive() && initargs[i] != null) {
434 initargs[i] = Method.toPrimitive(initargs[i]);
438 return (T) newInstance0(this.getDeclaringClass(), "cons__" + sig, initargs);
441 @JavaScriptBody(args = { "self", "sig", "args" }, body =
442 "\nvar c = self.cnstr;"
443 + "\nvar inst = c();"
444 + "\nc[sig].apply(inst, args);"
447 private static native Object newInstance0(Class<?> self, String sig, Object[] args);
450 * Returns {@code true} if this constructor was declared to take
451 * a variable number of arguments; returns {@code false}
454 * @return {@code true} if an only if this constructor was declared to
455 * take a variable number of arguments.
458 public boolean isVarArgs() {
459 return (getModifiers() & Modifier.VARARGS) != 0;
463 * Returns {@code true} if this constructor is a synthetic
464 * constructor; returns {@code false} otherwise.
466 * @return true if and only if this constructor is a synthetic
467 * constructor as defined by
468 * <cite>The Java™ Language Specification</cite>.
471 public boolean isSynthetic() {
472 return Modifier.isSynthetic(getModifiers());
476 * @throws NullPointerException {@inheritDoc}
479 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
480 if (annotationClass == null)
481 throw new NullPointerException();
483 return null; // XXX (T) declaredAnnotations().get(annotationClass);
489 public Annotation[] getDeclaredAnnotations() {
490 return new Annotation[0]; // XXX AnnotationParser.toArray(declaredAnnotations());
494 * Returns an array of arrays that represent the annotations on the formal
495 * parameters, in declaration order, of the method represented by
496 * this {@code Constructor} object. (Returns an array of length zero if the
497 * underlying method is parameterless. If the method has one or more
498 * parameters, a nested array of length zero is returned for each parameter
499 * with no annotations.) The annotation objects contained in the returned
500 * arrays are serializable. The caller of this method is free to modify
501 * the returned arrays; it will have no effect on the arrays returned to
504 * @return an array of arrays that represent the annotations on the formal
505 * parameters, in declaration order, of the method represented by this
509 public Annotation[][] getParameterAnnotations() {
510 // int numParameters = parameterTypes.length;
511 // if (parameterAnnotations == null)
512 // return new Annotation[numParameters][0];
514 return new Annotation[0][0]; // XXX
516 Annotation[][] result = AnnotationParser.parseParameterAnnotations(
517 parameterAnnotations,
518 sun.misc.SharedSecrets.getJavaLangAccess().
519 getConstantPool(getDeclaringClass()),
520 getDeclaringClass());
521 if (result.length != numParameters) {
522 Class<?> declaringClass = getDeclaringClass();
523 if (declaringClass.isEnum() ||
524 declaringClass.isAnonymousClass() ||
525 declaringClass.isLocalClass() )
526 ; // Can't do reliable parameter counting
528 if (!declaringClass.isMemberClass() || // top-level
529 // Check for the enclosing instance parameter for
530 // non-static member classes
531 (declaringClass.isMemberClass() &&
532 ((declaringClass.getModifiers() & Modifier.STATIC) == 0) &&
533 result.length + 1 != numParameters) ) {
534 throw new AnnotationFormatError(
535 "Parameter annotations don't match number of parameters");