1 /* java.lang.reflect.Constructor - reflection of Java constructors
2 Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package java.lang.reflect;
41 import gnu.java.lang.ClassHelper;
43 import gnu.java.lang.reflect.MethodSignatureParser;
45 import java.lang.annotation.Annotation;
47 import java.util.Arrays;
50 * The Constructor class represents a constructor of a class. It also allows
51 * dynamic creation of an object, via reflection. Invocation on Constructor
52 * objects knows how to do widening conversions, but throws
53 * {@link IllegalArgumentException} if a narrowing conversion would be
54 * necessary. You can query for information on this Constructor regardless
55 * of location, but construction access may be limited by Java language
56 * access controls. If you can't do it in the compiler, you can't normally
57 * do it here either.<p>
59 * <B>Note:</B> This class returns and accepts types as Classes, even
60 * primitive types; there are Class types defined that represent each
61 * different primitive type. They are <code>java.lang.Boolean.TYPE,
62 * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
63 * byte.class</code>, etc. These are not to be confused with the
64 * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
67 * Also note that this is not a serializable class. It is entirely feasible
68 * to make it serializable using the Externalizable interface, but this is
72 * @author Eric Blake <ebb9@email.byu.edu>
75 * @see java.lang.Class#getConstructor(Class[])
76 * @see java.lang.Class#getDeclaredConstructor(Class[])
77 * @see java.lang.Class#getConstructors()
78 * @see java.lang.Class#getDeclaredConstructors()
80 * @status updated to 1.4
82 public final class Constructor<T>
83 extends AccessibleObject
84 implements GenericDeclaration, Member
86 private Class<T> clazz;
90 * Unparsed annotations.
92 private byte[] annotations = null;
95 * Unparsed parameter annotations.
97 private byte[] parameterAnnotations = null;
100 * Annotations get parsed the first time they are
101 * accessed and are then cached it this map.
103 private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations = null;
105 private static final int CONSTRUCTOR_MODIFIERS
106 = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
109 * Helper array for creating a new array from a java.util.Container.
111 private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
115 * This class is uninstantiable except from native code.
117 private Constructor(Class declaringClass,int slot)
119 this.clazz = declaringClass;
123 private Constructor()
128 * Gets the class that declared this constructor.
129 * @return the class that declared this member
131 public Class<T> getDeclaringClass()
137 * Gets the name of this constructor (the non-qualified name of the class
138 * it was declared in).
139 * @return the name of this constructor
141 public String getName()
143 return getDeclaringClass().getName();
147 * Return the raw modifiers for this constructor. In particular
148 * this will include the synthetic and varargs bits.
149 * @return the constructor's modifiers
151 private native int getModifiersInternal();
154 * Gets the modifiers this constructor uses. Use the <code>Modifier</code>
155 * class to interpret the values. A constructor can only have a subset of the
156 * following modifiers: public, private, protected.
158 * @return an integer representing the modifiers to this Member
161 public int getModifiers()
163 return getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
167 * Return true if this constructor is synthetic, false otherwise.
168 * A synthetic member is one which is created by the compiler,
169 * and which does not appear in the user's source code.
172 public boolean isSynthetic()
174 return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
178 * Return true if this is a varargs constructor, that is if
179 * the constructor takes a variable number of arguments.
182 public boolean isVarArgs()
184 return (getModifiersInternal() & Modifier.VARARGS) != 0;
188 * Get the parameter list for this constructor, in declaration order. If the
189 * constructor takes no parameters, returns a 0-length array (not null).
191 * @return a list of the types of the constructor's parameters
193 public native Class<?>[] getParameterTypes();
196 * Get the exception types this constructor says it throws, in no particular
197 * order. If the constructor has no throws clause, returns a 0-length array
200 * @return a list of the types in the constructor's throws clause
202 public native Class<?>[] getExceptionTypes();
205 * Compare two objects to see if they are semantically equivalent.
206 * Two Constructors are semantically equivalent if they have the same
207 * declaring class and the same parameter list. This ignores different
208 * exception clauses, but since you can't create a Method except through the
209 * VM, this is just the == relation.
211 * @param o the object to compare to
212 * @return <code>true</code> if they are equal; <code>false</code> if not.
214 public boolean equals(Object o)
216 if (!(o instanceof Constructor))
218 Constructor that = (Constructor)o;
219 if (this.getDeclaringClass() != that.getDeclaringClass())
221 if (!Arrays.equals(this.getParameterTypes(), that.getParameterTypes()))
227 * Get the hash code for the Constructor. The Constructor hash code is the
228 * hash code of the declaring class's name.
230 * @return the hash code for the object
232 public int hashCode()
234 return getDeclaringClass().getName().hashCode();
238 * Get a String representation of the Constructor. A Constructor's String
239 * representation is "<modifier> <classname>(<paramtypes>)
240 * throws <exceptions>", where everything after ')' is omitted if
241 * there are no exceptions.<br> Example:
242 * <code>public java.io.FileInputStream(java.lang.Runnable)
243 * throws java.io.FileNotFoundException</code>
245 * @return the String representation of the Constructor
247 public String toString()
249 // 128 is a reasonable buffer initial size for constructor
250 StringBuilder sb = new StringBuilder(128);
251 Modifier.toString(getModifiers(), sb).append(' ');
252 sb.append(getDeclaringClass().getName()).append('(');
253 Class[] c = getParameterTypes();
256 sb.append(ClassHelper.getUserName(c[0]));
257 for (int i = 1; i < c.length; i++)
258 sb.append(',').append(ClassHelper.getUserName(c[i]));
261 c = getExceptionTypes();
264 sb.append(" throws ").append(c[0].getName());
265 for (int i = 1; i < c.length; i++)
266 sb.append(',').append(c[i].getName());
268 return sb.toString();
271 static <X extends GenericDeclaration>
272 void addTypeParameters(StringBuilder sb, TypeVariable<X>[] typeArgs)
274 if (typeArgs.length == 0)
277 for (int i = 0; i < typeArgs.length; ++i)
281 sb.append(typeArgs[i]);
286 public String toGenericString()
288 StringBuilder sb = new StringBuilder(128);
289 Modifier.toString(getModifiers(), sb).append(' ');
290 addTypeParameters(sb, getTypeParameters());
291 sb.append(getDeclaringClass().getName()).append('(');
292 Type[] types = getGenericParameterTypes();
293 if (types.length > 0)
296 for (int i = 1; i < types.length; ++i)
297 sb.append(',').append(types[i]);
300 types = getGenericExceptionTypes();
301 if (types.length > 0)
303 sb.append(" throws ").append(types[0]);
304 for (int i = 1; i < types.length; i++)
305 sb.append(',').append(types[i]);
307 return sb.toString();
311 * Create a new instance by invoking the constructor. Arguments are
312 * automatically unwrapped and widened, if needed.<p>
314 * If this class is abstract, you will get an
315 * <code>InstantiationException</code>. If the constructor takes 0
316 * arguments, you may use null or a 0-length array for <code>args</code>.<p>
318 * If this Constructor enforces access control, your runtime context is
319 * evaluated, and you may have an <code>IllegalAccessException</code> if
320 * you could not create this object in similar compiled code. If the class
321 * is uninitialized, you trigger class initialization, which may end in a
322 * <code>ExceptionInInitializerError</code>.<p>
324 * Then, the constructor is invoked. If it completes normally, the return
325 * value will be the new object. If it completes abruptly, the exception is
326 * wrapped in an <code>InvocationTargetException</code>.
328 * @param args the arguments to the constructor
329 * @return the newly created object
330 * @throws IllegalAccessException if the constructor could not normally be
331 * called by the Java code (i.e. it is not public)
332 * @throws IllegalArgumentException if the number of arguments is incorrect;
333 * or if the arguments types are wrong even with a widening
335 * @throws InstantiationException if the class is abstract
336 * @throws InvocationTargetException if the constructor throws an exception
337 * @throws ExceptionInInitializerError if construction triggered class
338 * initialization, which then failed
340 public T newInstance(Object... args)
341 throws InstantiationException, IllegalAccessException,
342 InvocationTargetException
344 return constructNative(args, clazz, slot);
347 private native T constructNative(Object[] args, Class declaringClass,
349 throws InstantiationException, IllegalAccessException,
350 InvocationTargetException;
353 * Returns an array of <code>TypeVariable</code> objects that represents
354 * the type variables declared by this constructor, in declaration order.
355 * An array of size zero is returned if this constructor has no type
358 * @return the type variables associated with this constructor.
359 * @throws GenericSignatureFormatError if the generic signature does
360 * not conform to the format specified in the Virtual Machine
361 * specification, version 3.
364 public TypeVariable<Constructor<T>>[] getTypeParameters()
366 String sig = getSignature();
368 return new TypeVariable[0];
369 MethodSignatureParser p = new MethodSignatureParser(this, sig);
370 return p.getTypeParameters();
374 * Return the String in the Signature attribute for this constructor. If there
375 * is no Signature attribute, return null.
377 private native String getSignature();
380 * Returns an array of <code>Type</code> objects that represents
381 * the exception types declared by this constructor, in declaration order.
382 * An array of size zero is returned if this constructor declares no
385 * @return the exception types declared by this constructor.
386 * @throws GenericSignatureFormatError if the generic signature does
387 * not conform to the format specified in the Virtual Machine
388 * specification, version 3.
391 public Type[] getGenericExceptionTypes()
393 String sig = getSignature();
395 return getExceptionTypes();
396 MethodSignatureParser p = new MethodSignatureParser(this, sig);
397 return p.getGenericExceptionTypes();
401 * Returns an array of <code>Type</code> objects that represents
402 * the parameter list for this constructor, in declaration order.
403 * An array of size zero is returned if this constructor takes no
406 * @return a list of the types of the constructor's parameters
407 * @throws GenericSignatureFormatError if the generic signature does
408 * not conform to the format specified in the Virtual Machine
409 * specification, version 3.
412 public Type[] getGenericParameterTypes()
414 String sig = getSignature();
416 return getParameterTypes();
417 MethodSignatureParser p = new MethodSignatureParser(this, sig);
418 return p.getGenericParameterTypes();
422 * @throws NullPointerException {@inheritDoc}
425 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
426 if (annotationClass == null)
427 throw new NullPointerException();
429 return (T)declaredAnnotations().get(annotationClass);
435 public Annotation[] getDeclaredAnnotations() {
436 return declaredAnnotations().values().toArray(EMPTY_ANNOTATIONS_ARRAY);
440 * Parses the annotations if they aren't parsed yet and stores them into
441 * the declaredAnnotations map and return this map.
443 private synchronized native Map<Class<? extends Annotation>, Annotation> declaredAnnotations();
446 * Returns an array of arrays that represent the annotations on the formal
447 * parameters, in declaration order, of the method represented by
448 * this <tt>Method</tt> object. (Returns an array of length zero if the
449 * underlying method is parameterless. If the method has one or more
450 * parameters, a nested array of length zero is returned for each parameter
451 * with no annotations.) The annotation objects contained in the returned
452 * arrays are serializable. The caller of this method is free to modify
453 * the returned arrays; it will have no effect on the arrays returned to
456 * @return an array of arrays that represent the annotations on the formal
457 * parameters, in declaration order, of the method represented by this
461 public native Annotation[][] getParameterAnnotations();