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
;
46 import java
.util
.Arrays
;
49 * The Constructor class represents a constructor of a class. It also allows
50 * dynamic creation of an object, via reflection. Invocation on Constructor
51 * objects knows how to do widening conversions, but throws
52 * {@link IllegalArgumentException} if a narrowing conversion would be
53 * necessary. You can query for information on this Constructor regardless
54 * of location, but construction access may be limited by Java language
55 * access controls. If you can't do it in the compiler, you can't normally
56 * do it here either.<p>
58 * <B>Note:</B> This class returns and accepts types as Classes, even
59 * primitive types; there are Class types defined that represent each
60 * different primitive type. They are <code>java.lang.Boolean.TYPE,
61 * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
62 * byte.class</code>, etc. These are not to be confused with the
63 * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
66 * Also note that this is not a serializable class. It is entirely feasible
67 * to make it serializable using the Externalizable interface, but this is
71 * @author Eric Blake <ebb9@email.byu.edu>
74 * @see java.lang.Class#getConstructor(Class[])
75 * @see java.lang.Class#getDeclaredConstructor(Class[])
76 * @see java.lang.Class#getConstructors()
77 * @see java.lang.Class#getDeclaredConstructors()
79 * @status updated to 1.4
81 public final class Constructor
<T
>
82 extends AccessibleObject
83 implements GenericDeclaration
, Member
85 private Class
<T
> clazz
;
88 private static final int CONSTRUCTOR_MODIFIERS
89 = Modifier
.PRIVATE
| Modifier
.PROTECTED
| Modifier
.PUBLIC
;
92 * This class is uninstantiable except from native code.
94 private Constructor(Class declaringClass
,int slot
)
96 this.clazz
= declaringClass
;
100 private Constructor()
105 * Gets the class that declared this constructor.
106 * @return the class that declared this member
108 public Class
<T
> getDeclaringClass()
114 * Gets the name of this constructor (the non-qualified name of the class
115 * it was declared in).
116 * @return the name of this constructor
118 public String
getName()
120 return getDeclaringClass().getName();
124 * Return the raw modifiers for this constructor. In particular
125 * this will include the synthetic and varargs bits.
126 * @return the constructor's modifiers
128 private native int getModifiersInternal();
131 * Gets the modifiers this constructor uses. Use the <code>Modifier</code>
132 * class to interpret the values. A constructor can only have a subset of the
133 * following modifiers: public, private, protected.
135 * @return an integer representing the modifiers to this Member
138 public int getModifiers()
140 return getModifiersInternal() & CONSTRUCTOR_MODIFIERS
;
144 * Return true if this constructor is synthetic, false otherwise.
145 * A synthetic member is one which is created by the compiler,
146 * and which does not appear in the user's source code.
149 public boolean isSynthetic()
151 return (getModifiersInternal() & Modifier
.SYNTHETIC
) != 0;
155 * Return true if this is a varargs constructor, that is if
156 * the constructor takes a variable number of arguments.
159 public boolean isVarArgs()
161 return (getModifiersInternal() & Modifier
.VARARGS
) != 0;
165 * Get the parameter list for this constructor, in declaration order. If the
166 * constructor takes no parameters, returns a 0-length array (not null).
168 * @return a list of the types of the constructor's parameters
170 public native Class
<?
>[] getParameterTypes();
173 * Get the exception types this constructor says it throws, in no particular
174 * order. If the constructor has no throws clause, returns a 0-length array
177 * @return a list of the types in the constructor's throws clause
179 public native Class
<?
>[] getExceptionTypes();
182 * Compare two objects to see if they are semantically equivalent.
183 * Two Constructors are semantically equivalent if they have the same
184 * declaring class and the same parameter list. This ignores different
185 * exception clauses, but since you can't create a Method except through the
186 * VM, this is just the == relation.
188 * @param o the object to compare to
189 * @return <code>true</code> if they are equal; <code>false</code> if not.
191 public boolean equals(Object o
)
193 if (!(o
instanceof Constructor
))
195 Constructor that
= (Constructor
)o
;
196 if (this.getDeclaringClass() != that
.getDeclaringClass())
198 if (!Arrays
.equals(this.getParameterTypes(), that
.getParameterTypes()))
204 * Get the hash code for the Constructor. The Constructor hash code is the
205 * hash code of the declaring class's name.
207 * @return the hash code for the object
209 public int hashCode()
211 return getDeclaringClass().getName().hashCode();
215 * Get a String representation of the Constructor. A Constructor's String
216 * representation is "<modifier> <classname>(<paramtypes>)
217 * throws <exceptions>", where everything after ')' is omitted if
218 * there are no exceptions.<br> Example:
219 * <code>public java.io.FileInputStream(java.lang.Runnable)
220 * throws java.io.FileNotFoundException</code>
222 * @return the String representation of the Constructor
224 public String
toString()
226 // 128 is a reasonable buffer initial size for constructor
227 StringBuilder sb
= new StringBuilder(128);
228 Modifier
.toString(getModifiers(), sb
).append(' ');
229 sb
.append(getDeclaringClass().getName()).append('(');
230 Class
[] c
= getParameterTypes();
233 sb
.append(ClassHelper
.getUserName(c
[0]));
234 for (int i
= 1; i
< c
.length
; i
++)
235 sb
.append(',').append(ClassHelper
.getUserName(c
[i
]));
238 c
= getExceptionTypes();
241 sb
.append(" throws ").append(c
[0].getName());
242 for (int i
= 1; i
< c
.length
; i
++)
243 sb
.append(',').append(c
[i
].getName());
245 return sb
.toString();
248 static <X
extends GenericDeclaration
>
249 void addTypeParameters(StringBuilder sb
, TypeVariable
<X
>[] typeArgs
)
251 if (typeArgs
.length
== 0)
254 for (int i
= 0; i
< typeArgs
.length
; ++i
)
258 sb
.append(typeArgs
[i
]);
263 public String
toGenericString()
265 StringBuilder sb
= new StringBuilder(128);
266 Modifier
.toString(getModifiers(), sb
).append(' ');
267 addTypeParameters(sb
, getTypeParameters());
268 sb
.append(getDeclaringClass().getName()).append('(');
269 Type
[] types
= getGenericParameterTypes();
270 if (types
.length
> 0)
273 for (int i
= 1; i
< types
.length
; ++i
)
274 sb
.append(',').append(types
[i
]);
277 types
= getGenericExceptionTypes();
278 if (types
.length
> 0)
280 sb
.append(" throws ").append(types
[0]);
281 for (int i
= 1; i
< types
.length
; i
++)
282 sb
.append(',').append(types
[i
]);
284 return sb
.toString();
288 * Create a new instance by invoking the constructor. Arguments are
289 * automatically unwrapped and widened, if needed.<p>
291 * If this class is abstract, you will get an
292 * <code>InstantiationException</code>. If the constructor takes 0
293 * arguments, you may use null or a 0-length array for <code>args</code>.<p>
295 * If this Constructor enforces access control, your runtime context is
296 * evaluated, and you may have an <code>IllegalAccessException</code> if
297 * you could not create this object in similar compiled code. If the class
298 * is uninitialized, you trigger class initialization, which may end in a
299 * <code>ExceptionInInitializerError</code>.<p>
301 * Then, the constructor is invoked. If it completes normally, the return
302 * value will be the new object. If it completes abruptly, the exception is
303 * wrapped in an <code>InvocationTargetException</code>.
305 * @param args the arguments to the constructor
306 * @return the newly created object
307 * @throws IllegalAccessException if the constructor could not normally be
308 * called by the Java code (i.e. it is not public)
309 * @throws IllegalArgumentException if the number of arguments is incorrect;
310 * or if the arguments types are wrong even with a widening
312 * @throws InstantiationException if the class is abstract
313 * @throws InvocationTargetException if the constructor throws an exception
314 * @throws ExceptionInInitializerError if construction triggered class
315 * initialization, which then failed
317 public T
newInstance(Object
... args
)
318 throws InstantiationException
, IllegalAccessException
,
319 InvocationTargetException
321 return constructNative(args
, clazz
, slot
);
324 private native T
constructNative(Object
[] args
, Class declaringClass
,
326 throws InstantiationException
, IllegalAccessException
,
327 InvocationTargetException
;
330 * Returns an array of <code>TypeVariable</code> objects that represents
331 * the type variables declared by this constructor, in declaration order.
332 * An array of size zero is returned if this constructor has no type
335 * @return the type variables associated with this constructor.
336 * @throws GenericSignatureFormatError if the generic signature does
337 * not conform to the format specified in the Virtual Machine
338 * specification, version 3.
341 public TypeVariable
<Constructor
<T
>>[] getTypeParameters()
343 String sig
= getSignature();
345 return new TypeVariable
[0];
346 MethodSignatureParser p
= new MethodSignatureParser(this, sig
);
347 return p
.getTypeParameters();
351 * Return the String in the Signature attribute for this constructor. If there
352 * is no Signature attribute, return null.
354 private native String
getSignature();
357 * Returns an array of <code>Type</code> objects that represents
358 * the exception types declared by this constructor, in declaration order.
359 * An array of size zero is returned if this constructor declares no
362 * @return the exception types declared by this constructor.
363 * @throws GenericSignatureFormatError if the generic signature does
364 * not conform to the format specified in the Virtual Machine
365 * specification, version 3.
368 public Type
[] getGenericExceptionTypes()
370 String sig
= getSignature();
372 return getExceptionTypes();
373 MethodSignatureParser p
= new MethodSignatureParser(this, sig
);
374 return p
.getGenericExceptionTypes();
378 * Returns an array of <code>Type</code> objects that represents
379 * the parameter list for this constructor, in declaration order.
380 * An array of size zero is returned if this constructor takes no
383 * @return a list of the types of the constructor's parameters
384 * @throws GenericSignatureFormatError if the generic signature does
385 * not conform to the format specified in the Virtual Machine
386 * specification, version 3.
389 public Type
[] getGenericParameterTypes()
391 String sig
= getSignature();
393 return getParameterTypes();
394 MethodSignatureParser p
= new MethodSignatureParser(this, sig
);
395 return p
.getGenericParameterTypes();
400 * Return an array of arrays representing the annotations on each
401 * of the constructor's parameters. The outer array is aligned against
402 * the parameters of the constructors and is thus equal in length to
403 * the number of parameters (thus having a length zero if there are none).
404 * Each array element in the outer array contains an inner array which
405 * holds the annotations. This array has a length of zero if the parameter
406 * has no annotations.
409 * The returned annotations are serialized. Changing the annotations has
410 * no affect on the return value of future calls to this method.
413 * @return an array of arrays which represents the annotations used on the
414 * parameters of this constructor. The order of the array elements
415 * matches the declaration order of the parameters.
418 public native Annotation
[][] getParameterAnnotations();