* src/classes/Makefile.am (BOOTCLASSPATH): Removed, this is set during
[cacao.git] / src / classes / gnu / java / lang / reflect / Constructor.java
1 /* java.lang.reflect.Constructor - reflection of Java constructors
2    Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
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)
9 any later version.
10  
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.
15
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
19 02110-1301 USA.
20
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
24 combination.
25
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. */
37
38
39 package java.lang.reflect;
40
41 import gnu.java.lang.ClassHelper;
42 import gnu.java.lang.CPStringBuilder;
43
44 import gnu.java.lang.reflect.MethodSignatureParser;
45
46 import java.lang.annotation.Annotation;
47
48 /**
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>
57  *
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
64  * real classes.<p>
65  *
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
68  * on Sun, not me.
69  *
70  * @author John Keiser
71  * @author Eric Blake <ebb9@email.byu.edu>
72  * @see Member
73  * @see Class
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()
78  * @since 1.1
79  * @status updated to 1.4
80  */
81 public final class Constructor<T>
82   extends AccessibleObject
83   implements GenericDeclaration, Member
84 {  
85   private static final int CONSTRUCTOR_MODIFIERS
86     = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
87
88   private MethodSignatureParser p;
89
90   VMConstructor cons;
91
92   /**
93    * This class is uninstantiable outside this package.
94    */
95   Constructor(VMConstructor cons)
96   {
97     this.cons = cons;
98     cons.cons = this;
99   }
100
101   private Constructor()
102   {
103   }
104
105   /**
106    * Gets the class that declared this constructor.
107    * @return the class that declared this member
108    */
109   @SuppressWarnings("unchecked")
110   public Class<T> getDeclaringClass()
111   {
112     return (Class<T>) cons.getDeclaringClass();
113   }
114
115   /**
116    * Gets the name of this constructor (the non-qualified name of the class
117    * it was declared in).
118    * @return the name of this constructor
119    */
120   public String getName()
121   {
122     return cons.getDeclaringClass().getName();
123   }
124
125   /**
126    * Gets the modifiers this constructor uses.  Use the <code>Modifier</code>
127    * class to interpret the values. A constructor can only have a subset of the
128    * following modifiers: public, private, protected.
129    *
130    * @return an integer representing the modifiers to this Member
131    * @see Modifier
132    */
133   public int getModifiers()
134   {
135     return cons.getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
136   }
137
138   /**
139    * Return true if this constructor is synthetic, false otherwise.
140    * A synthetic member is one which is created by the compiler,
141    * and which does not appear in the user's source code.
142    * @since 1.5
143    */
144   public boolean isSynthetic()
145   {
146     return (cons.getModifiersInternal() & Modifier.SYNTHETIC) != 0;
147   }
148
149   /**
150    * Return true if this is a varargs constructor, that is if
151    * the constructor takes a variable number of arguments.
152    * @since 1.5
153    */
154   public boolean isVarArgs()
155   {
156     return (cons.getModifiersInternal() & Modifier.VARARGS) != 0;
157   }
158
159   /**
160    * Get the parameter list for this constructor, in declaration order. If the
161    * constructor takes no parameters, returns a 0-length array (not null).
162    *
163    * @return a list of the types of the constructor's parameters
164    */
165   @SuppressWarnings("unchecked")
166   public Class<?>[] getParameterTypes()
167   {
168     return (Class<?>[]) cons.getParameterTypes();
169   }
170
171   /**
172    * Get the exception types this constructor says it throws, in no particular
173    * order. If the constructor has no throws clause, returns a 0-length array
174    * (not null).
175    *
176    * @return a list of the types in the constructor's throws clause
177    */
178   @SuppressWarnings("unchecked")
179   public Class<?>[] getExceptionTypes()
180   {
181     return (Class<?>[]) cons.getExceptionTypes();
182   }
183
184   /**
185    * Compare two objects to see if they are semantically equivalent.
186    * Two Constructors are semantically equivalent if they have the same
187    * declaring class and the same parameter list.  This ignores different
188    * exception clauses, but since you can't create a Method except through the
189    * VM, this is just the == relation.
190    *
191    * @param o the object to compare to
192    * @return <code>true</code> if they are equal; <code>false</code> if not.
193    */
194   public boolean equals(Object o)
195   {
196     return cons.equals(o);
197   }
198
199   /**
200    * Get the hash code for the Constructor. The Constructor hash code is the
201    * hash code of the declaring class's name.
202    *
203    * @return the hash code for the object
204    */
205   public int hashCode()
206   {
207     return getName().hashCode();
208   }
209
210   /**
211    * Get a String representation of the Constructor. A Constructor's String
212    * representation is "&lt;modifier&gt; &lt;classname&gt;(&lt;paramtypes&gt;)
213    * throws &lt;exceptions&gt;", where everything after ')' is omitted if
214    * there are no exceptions.<br> Example:
215    * <code>public java.io.FileInputStream(java.lang.Runnable)
216    * throws java.io.FileNotFoundException</code>
217    *
218    * @return the String representation of the Constructor
219    */
220   public String toString()
221   {
222     // 128 is a reasonable buffer initial size for constructor
223     CPStringBuilder sb = new CPStringBuilder(128);
224     Modifier.toString(getModifiers(), sb).append(' ');
225     sb.append(getDeclaringClass().getName()).append('(');
226     Class[] c = getParameterTypes();
227     if (c.length > 0)
228       {
229         sb.append(ClassHelper.getUserName(c[0]));
230         for (int i = 1; i < c.length; i++)
231           sb.append(',').append(ClassHelper.getUserName(c[i]));
232       }
233     sb.append(')');
234     c = getExceptionTypes();
235     if (c.length > 0)
236       {
237         sb.append(" throws ").append(c[0].getName());
238         for (int i = 1; i < c.length; i++)
239           sb.append(',').append(c[i].getName());
240       }
241     return sb.toString();
242   }
243
244   static <X extends GenericDeclaration>
245   void addTypeParameters(CPStringBuilder sb, TypeVariable<X>[] typeArgs)
246   {
247     if (typeArgs.length == 0)
248       return;
249     sb.append('<');
250     for (int i = 0; i < typeArgs.length; ++i)
251       {
252         if (i > 0)
253           sb.append(',');
254         sb.append(typeArgs[i]);
255       }
256     sb.append("> ");
257   }
258
259   public String toGenericString()
260   {
261     CPStringBuilder sb = new CPStringBuilder(128);
262     Modifier.toString(getModifiers(), sb).append(' ');
263     addTypeParameters(sb, getTypeParameters());
264     sb.append(getDeclaringClass().getName()).append('(');
265     Type[] types = getGenericParameterTypes();
266     if (types.length > 0)
267       {
268         sb.append(types[0]);
269         for (int i = 1; i < types.length; ++i)
270           sb.append(',').append(types[i]);
271       }
272     sb.append(')');
273     types = getGenericExceptionTypes();
274     if (types.length > 0)
275       {
276         sb.append(" throws ").append(types[0]);
277         for (int i = 1; i < types.length; i++)
278           sb.append(',').append(types[i]);
279       }
280     return sb.toString();
281   }
282
283   /**
284    * Create a new instance by invoking the constructor. Arguments are
285    * automatically unwrapped and widened, if needed.<p>
286    *
287    * If this class is abstract, you will get an
288    * <code>InstantiationException</code>. If the constructor takes 0
289    * arguments, you may use null or a 0-length array for <code>args</code>.<p>
290    *
291    * If this Constructor enforces access control, your runtime context is
292    * evaluated, and you may have an <code>IllegalAccessException</code> if
293    * you could not create this object in similar compiled code. If the class
294    * is uninitialized, you trigger class initialization, which may end in a
295    * <code>ExceptionInInitializerError</code>.<p>
296    *
297    * Then, the constructor is invoked. If it completes normally, the return
298    * value will be the new object. If it completes abruptly, the exception is
299    * wrapped in an <code>InvocationTargetException</code>.
300    *
301    * @param args the arguments to the constructor
302    * @return the newly created object
303    * @throws IllegalAccessException if the constructor could not normally be
304    *         called by the Java code (i.e. it is not public)
305    * @throws IllegalArgumentException if the number of arguments is incorrect;
306    *         or if the arguments types are wrong even with a widening
307    *         conversion
308    * @throws InstantiationException if the class is abstract
309    * @throws InvocationTargetException if the constructor throws an exception
310    * @throws ExceptionInInitializerError if construction triggered class
311    *         initialization, which then failed
312    */
313   @SuppressWarnings("unchecked")
314   public T newInstance(Object... args)
315     throws InstantiationException, IllegalAccessException,
316            InvocationTargetException
317   {
318     return (T) cons.construct(args);
319   }
320
321   /**
322    * Returns an array of <code>TypeVariable</code> objects that represents
323    * the type variables declared by this constructor, in declaration order.
324    * An array of size zero is returned if this constructor has no type
325    * variables.
326    *
327    * @return the type variables associated with this constructor.
328    * @throws GenericSignatureFormatError if the generic signature does
329    *         not conform to the format specified in the Virtual Machine
330    *         specification, version 3.
331    * @since 1.5
332    */
333   public TypeVariable<Constructor<T>>[] getTypeParameters()
334   {
335     if (p == null)
336       {
337         String sig = cons.getSignature();
338         if (sig == null)
339           return new TypeVariable[0];
340         p = new MethodSignatureParser(this, sig);
341       }
342     return p.getTypeParameters();
343   }
344
345   /**
346    * Returns an array of <code>Type</code> objects that represents
347    * the exception types declared by this constructor, in declaration order.
348    * An array of size zero is returned if this constructor declares no
349    * exceptions.
350    *
351    * @return the exception types declared by this constructor. 
352    * @throws GenericSignatureFormatError if the generic signature does
353    *         not conform to the format specified in the Virtual Machine
354    *         specification, version 3.
355    * @since 1.5
356    */
357   public Type[] getGenericExceptionTypes()
358   {
359     if (p == null)
360       {
361         String sig = cons.getSignature();
362         if (sig == null)
363           return getExceptionTypes();
364         p = new MethodSignatureParser(this, sig);
365       }
366     return p.getGenericExceptionTypes();
367   }
368
369   /**
370    * Returns an array of <code>Type</code> objects that represents
371    * the parameter list for this constructor, in declaration order.
372    * An array of size zero is returned if this constructor takes no
373    * parameters.
374    *
375    * @return a list of the types of the constructor's parameters
376    * @throws GenericSignatureFormatError if the generic signature does
377    *         not conform to the format specified in the Virtual Machine
378    *         specification, version 3.
379    * @since 1.5
380    */
381   public Type[] getGenericParameterTypes()
382   {
383     if (p == null)
384       {
385         String sig = cons.getSignature();
386         if (sig == null)
387           return getParameterTypes();
388         p = new MethodSignatureParser(this, sig);
389       }
390     return p.getGenericParameterTypes();
391   }
392
393   /**
394    * <p>
395    * Return an array of arrays representing the annotations on each
396    * of the constructor's parameters.  The outer array is aligned against
397    * the parameters of the constructors and is thus equal in length to
398    * the number of parameters (thus having a length zero if there are none).
399    * Each array element in the outer array contains an inner array which
400    * holds the annotations.  This array has a length of zero if the parameter
401    * has no annotations.
402    * </p>
403    * <p>
404    * The returned annotations are serialized.  Changing the annotations has
405    * no affect on the return value of future calls to this method.
406    * </p>
407    * 
408    * @return an array of arrays which represents the annotations used on the
409    *         parameters of this constructor.  The order of the array elements
410    *         matches the declaration order of the parameters.
411    * @since 1.5
412    */
413   public Annotation[][] getParameterAnnotations()
414   {
415     return cons.getParameterAnnotations();
416   }
417
418   /**
419    * Returns the element's annotation for the specified annotation type,
420    * or <code>null</code> if no such annotation exists.
421    *
422    * @param annotationClass the type of annotation to look for.
423    * @return this element's annotation for the specified type, or
424    *         <code>null</code> if no such annotation exists.
425    * @throws NullPointerException if the annotation class is <code>null</code>.
426    */
427   @SuppressWarnings("unchecked")
428   public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
429   {
430     return (T) cons.getAnnotation(annotationClass);
431   }
432
433   /**
434    * Returns all annotations directly defined by the element.  If there are
435    * no annotations directly associated with the element, then a zero-length
436    * array will be returned.  The returned array may be modified by the client
437    * code, but this will have no effect on the annotation content of this
438    * class, and hence no effect on the return value of this method for
439    * future callers.
440    *
441    * @return the annotations directly defined by the element.
442    * @since 1.5
443    */
444   public Annotation[] getDeclaredAnnotations()
445   {
446     return cons.getDeclaredAnnotations();
447   }
448
449 }