1 /* java.lang.reflect.Constructor - reflection of Java constructors
2 Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
40 package java.lang.reflect;
42 import gnu.java.lang.reflect.MethodSignatureParser;
43 import java.lang.annotation.Annotation;
46 * The Constructor class represents a constructor of a class. It also allows
47 * dynamic creation of an object, via reflection. Invocation on Constructor
48 * objects knows how to do widening conversions, but throws
49 * {@link IllegalArgumentException} if a narrowing conversion would be
50 * necessary. You can query for information on this Constructor regardless
51 * of location, but construction access may be limited by Java language
52 * access controls. If you can't do it in the compiler, you can't normally
53 * do it here either.<p>
55 * <B>Note:</B> This class returns and accepts types as Classes, even
56 * primitive types; there are Class types defined that represent each
57 * different primitive type. They are <code>java.lang.Boolean.TYPE,
58 * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
59 * byte.class</code>, etc. These are not to be confused with the
60 * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
63 * Also note that this is not a serializable class. It is entirely feasible
64 * to make it serializable using the Externalizable interface, but this is
68 * @author Eric Blake <ebb9@email.byu.edu>
69 * @author Tom Tromey <tromey@redhat.com>
72 * @see java.lang.Class#getConstructor(Class[])
73 * @see java.lang.Class#getDeclaredConstructor(Class[])
74 * @see java.lang.Class#getConstructors()
75 * @see java.lang.Class#getDeclaredConstructors()
77 * @status updated to 1.4
79 public final class Constructor<T> extends AccessibleObject
80 implements Member, GenericDeclaration
82 private static final int CONSTRUCTOR_MODIFIERS
83 = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
86 * This class is uninstantiable except from native code.
88 private Constructor ()
93 * Gets the class that declared this constructor.
94 * @return the class that declared this member
96 public Class<T> getDeclaringClass ()
98 return declaringClass;
102 * Gets the name of this constructor (the non-qualified name of the class
103 * it was declared in).
104 * @return the name of this constructor
106 public String getName()
108 return declaringClass.getName();
112 * Return the raw modifiers for this constructor. In particular
113 * this will include the synthetic and varargs bits.
114 * @return the constructor's modifiers
116 private native int getModifiersInternal();
119 * Gets the modifiers this constructor uses. Use the <code>Modifier</code>
120 * class to interpret the values. A constructor can only have a subset of the
121 * following modifiers: public, private, protected.
123 * @return an integer representing the modifiers to this Member
126 public int getModifiers ()
128 return getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
132 * Return true if this constructor is synthetic, false otherwise.
133 * A synthetic member is one which is created by the compiler,
134 * and which does not appear in the user's source code.
137 public boolean isSynthetic()
139 return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
143 * Return true if this is a varargs constructor, that is if
144 * the constructor takes a variable number of arguments.
147 public boolean isVarArgs()
149 return (getModifiersInternal() & Modifier.VARARGS) != 0;
153 * Get the parameter list for this constructor, in declaration order. If the
154 * constructor takes no parameters, returns a 0-length array (not null).
156 * @return a list of the types of the constructor's parameters
158 public Class[] getParameterTypes ()
160 if (parameter_types == null)
162 return (Class[]) parameter_types.clone();
166 * Get the exception types this constructor says it throws, in no particular
167 * order. If the constructor has no throws clause, returns a 0-length array
170 * @return a list of the types in the constructor's throws clause
172 public Class[] getExceptionTypes ()
174 if (exception_types == null)
176 return (Class[]) exception_types.clone();
180 * Compare two objects to see if they are semantically equivalent.
181 * Two Constructors are semantically equivalent if they have the same
182 * declaring class and the same parameter list.
184 * @param o the object to compare to
185 * @return <code>true</code> if they are equal; <code>false</code> if not.
187 public boolean equals (Object obj)
189 if (! (obj instanceof Constructor))
191 Constructor c = (Constructor) obj;
192 return declaringClass == c.declaringClass && offset == c.offset;
196 * Get the hash code for the Constructor. The Constructor hash code is the
197 * hash code of the declaring class's name.
199 * @return the hash code for the object
201 public int hashCode ()
203 return declaringClass.getName().hashCode();
207 * Get a String representation of the Constructor. A Constructor's String
208 * representation is "<modifier> <classname>(<paramtypes>)
209 * throws <exceptions>", where everything after ')' is omitted if
210 * there are no exceptions.<br> Example:
211 * <code>public java.io.FileInputStream(java.lang.Runnable)
212 * throws java.io.FileNotFoundException</code>
214 * @return the String representation of the Constructor
216 public String toString()
218 if (parameter_types == null)
220 StringBuffer b = new StringBuffer ();
221 int mods = getModifiers();
224 Modifier.toString(mods, b);
227 Method.appendClassName (b, declaringClass);
229 for (int i = 0; i < parameter_types.length; ++i)
231 Method.appendClassName (b, parameter_types[i]);
232 if (i < parameter_types.length - 1)
239 static <X extends GenericDeclaration>
240 void addTypeParameters(StringBuilder sb, TypeVariable<X>[] typeArgs)
242 if (typeArgs.length == 0)
245 for (int i = 0; i < typeArgs.length; ++i)
249 sb.append(typeArgs[i]);
254 public String toGenericString()
256 StringBuilder sb = new StringBuilder(128);
257 Modifier.toString(getModifiers(), sb).append(' ');
258 addTypeParameters(sb, getTypeParameters());
259 sb.append(getDeclaringClass().getName()).append('(');
260 Type[] types = getGenericParameterTypes();
261 if (types.length > 0)
264 for (int i = 1; i < types.length; ++i)
265 sb.append(',').append(types[i]);
268 types = getGenericExceptionTypes();
269 if (types.length > 0)
271 sb.append(" throws ").append(types[0]);
272 for (int i = 1; i < types.length; i++)
273 sb.append(',').append(types[i]);
275 return sb.toString();
279 * Create a new instance by invoking the constructor. Arguments are
280 * automatically unwrapped and widened, if needed.<p>
282 * If this class is abstract, you will get an
283 * <code>InstantiationException</code>. If the constructor takes 0
284 * arguments, you may use null or a 0-length array for <code>args</code>.<p>
286 * If this Constructor enforces access control, your runtime context is
287 * evaluated, and you may have an <code>IllegalAccessException</code> if
288 * you could not create this object in similar compiled code. If the class
289 * is uninitialized, you trigger class initialization, which may end in a
290 * <code>ExceptionInInitializerError</code>.<p>
292 * Then, the constructor is invoked. If it completes normally, the return
293 * value will be the new object. If it completes abruptly, the exception is
294 * wrapped in an <code>InvocationTargetException</code>.
296 * @param args the arguments to the constructor
297 * @return the newly created object
298 * @throws IllegalAccessException if the constructor could not normally be
299 * called by the Java code (i.e. it is not public)
300 * @throws IllegalArgumentException if the number of arguments is incorrect;
301 * or if the arguments types are wrong even with a widening
303 * @throws InstantiationException if the class is abstract
304 * @throws InvocationTargetException if the constructor throws an exception
305 * @throws ExceptionInInitializerError if construction triggered class
306 * initialization, which then failed
308 public native Object newInstance (Object[] args)
309 throws InstantiationException, IllegalAccessException,
310 IllegalArgumentException, InvocationTargetException;
313 * Returns an array of <code>TypeVariable</code> objects that represents
314 * the type variables declared by this constructor, in declaration order.
315 * An array of size zero is returned if this constructor has no type
318 * @return the type variables associated with this constructor.
319 * @throws GenericSignatureFormatError if the generic signature does
320 * not conform to the format specified in the Virtual Machine
321 * specification, version 3.
324 public TypeVariable<Constructor<T>>[] getTypeParameters()
326 String sig = getSignature();
328 return new TypeVariable[0];
329 MethodSignatureParser p = new MethodSignatureParser(this, sig);
330 return p.getTypeParameters();
334 * Return the String in the Signature attribute for this constructor. If there
335 * is no Signature attribute, return null.
337 private native String getSignature();
340 * Returns an array of <code>Type</code> objects that represents
341 * the exception types declared by this constructor, in declaration order.
342 * An array of size zero is returned if this constructor declares no
345 * @return the exception types declared by this constructor.
346 * @throws GenericSignatureFormatError if the generic signature does
347 * not conform to the format specified in the Virtual Machine
348 * specification, version 3.
351 public Type[] getGenericExceptionTypes()
353 String sig = getSignature();
355 return getExceptionTypes();
356 MethodSignatureParser p = new MethodSignatureParser(this, sig);
357 return p.getGenericExceptionTypes();
361 * Returns an array of <code>Type</code> objects that represents
362 * the parameter list for this constructor, in declaration order.
363 * An array of size zero is returned if this constructor takes no
366 * @return a list of the types of the constructor's parameters
367 * @throws GenericSignatureFormatError if the generic signature does
368 * not conform to the format specified in the Virtual Machine
369 * specification, version 3.
372 public Type[] getGenericParameterTypes()
374 String sig = getSignature();
376 return getParameterTypes();
377 MethodSignatureParser p = new MethodSignatureParser(this, sig);
378 return p.getGenericParameterTypes();
381 public <T extends Annotation> T getAnnotation(Class<T> annoClass)
383 Annotation[] annos = getDeclaredAnnotations();
384 for (int i = 0; i < annos.length; ++i)
385 if (annos[i].annotationType() == annoClass)
390 public Annotation[] getDeclaredAnnotations()
392 Annotation[] result = getDeclaredAnnotationsInternal();
394 result = new Annotation[0];
398 public Annotation[][] getParameterAnnotations()
400 // FIXME: should check that we have the right number
401 // of parameters ...?
402 Annotation[][] result = getParameterAnnotationsInternal();
404 result = new Annotation[0][0];
408 private native Annotation[] getDeclaredAnnotationsInternal();
409 private native Annotation[][] getParameterAnnotationsInternal();
411 // Update cached values from method descriptor in class.
412 private native void getType ();
415 private Class<T> declaringClass;
418 private Class[] exception_types;
420 private Class[] parameter_types;
422 // Offset in bytes from the start of declaringClass's methods array.