001    /* java.lang.reflect.Constructor - reflection of Java constructors
002       Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007
003       Free Software Foundation, Inc.
004    
005    This file is part of GNU Classpath.
006    
007    GNU Classpath is free software; you can redistribute it and/or modify
008    it under the terms of the GNU General Public License as published by
009    the Free Software Foundation; either version 2, or (at your option)
010    any later version.
011     
012    GNU Classpath is distributed in the hope that it will be useful, but
013    WITHOUT ANY WARRANTY; without even the implied warranty of
014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015    General Public License for more details.
016    
017    You should have received a copy of the GNU General Public License
018    along with GNU Classpath; see the file COPYING.  If not, write to the
019    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
020    02110-1301 USA.
021    
022    Linking this library statically or dynamically with other modules is
023    making a combined work based on this library.  Thus, the terms and
024    conditions of the GNU General Public License cover the whole
025    combination.
026    
027    As a special exception, the copyright holders of this library give you
028    permission to link this library with independent modules to produce an
029    executable, regardless of the license terms of these independent
030    modules, and to copy and distribute the resulting executable under
031    terms of your choice, provided that you also meet, for each linked
032    independent module, the terms and conditions of the license of that
033    module.  An independent module is a module which is not derived from
034    or based on this library.  If you modify this library, you may extend
035    this exception to your version of the library, but you are not
036    obligated to do so.  If you do not wish to do so, delete this
037    exception statement from your version. */
038    
039    
040    package java.lang.reflect;
041    
042    import gnu.java.lang.reflect.MethodSignatureParser;
043    import java.lang.annotation.Annotation;
044    
045    /**
046     * The Constructor class represents a constructor of a class. It also allows
047     * dynamic creation of an object, via reflection. Invocation on Constructor
048     * objects knows how to do widening conversions, but throws
049     * {@link IllegalArgumentException} if a narrowing conversion would be
050     * necessary. You can query for information on this Constructor regardless
051     * of location, but construction access may be limited by Java language
052     * access controls. If you can't do it in the compiler, you can't normally
053     * do it here either.<p>
054     *
055     * <B>Note:</B> This class returns and accepts types as Classes, even
056     * primitive types; there are Class types defined that represent each
057     * different primitive type.  They are <code>java.lang.Boolean.TYPE,
058     * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
059     * byte.class</code>, etc.  These are not to be confused with the
060     * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
061     * real classes.<p>
062     *
063     * Also note that this is not a serializable class.  It is entirely feasible
064     * to make it serializable using the Externalizable interface, but this is
065     * on Sun, not me.
066     *
067     * @author John Keiser
068     * @author Eric Blake <ebb9@email.byu.edu>
069     * @author Tom Tromey <tromey@redhat.com>
070     * @see Member
071     * @see Class
072     * @see java.lang.Class#getConstructor(Class[])
073     * @see java.lang.Class#getDeclaredConstructor(Class[])
074     * @see java.lang.Class#getConstructors()
075     * @see java.lang.Class#getDeclaredConstructors()
076     * @since 1.1
077     * @status updated to 1.4
078     */
079    public final class Constructor<T> extends AccessibleObject
080      implements Member, GenericDeclaration
081    {
082      private static final int CONSTRUCTOR_MODIFIERS
083        = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
084    
085      /**
086       * This class is uninstantiable except from native code.
087       */
088      private Constructor ()
089      {
090      }
091    
092      /**
093       * Gets the class that declared this constructor.
094       * @return the class that declared this member
095       */
096      public Class<T> getDeclaringClass ()
097      {
098        return declaringClass;
099      }
100    
101      /**
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
105       */
106      public String getName()
107      {
108        return declaringClass.getName();
109      }
110    
111      /**
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
115       */
116      private native int getModifiersInternal();
117    
118      /**
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.
122       *
123       * @return an integer representing the modifiers to this Member
124       * @see Modifier
125       */
126      public int getModifiers ()
127      {
128        return getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
129      }
130    
131      /**
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.
135       * @since 1.5
136       */
137      public boolean isSynthetic()
138      {
139        return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
140      }
141    
142      /**
143       * Return true if this is a varargs constructor, that is if
144       * the constructor takes a variable number of arguments.
145       * @since 1.5
146       */
147      public boolean isVarArgs()
148      {
149        return (getModifiersInternal() & Modifier.VARARGS) != 0;
150      }
151    
152      /**
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).
155       *
156       * @return a list of the types of the constructor's parameters
157       */
158      public Class<?>[] getParameterTypes ()
159      {
160        if (parameter_types == null)
161          getType ();
162        return (Class<?>[]) parameter_types.clone();
163      }
164    
165      /**
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
168       * (not null).
169       *
170       * @return a list of the types in the constructor's throws clause
171       */
172      public Class<?>[] getExceptionTypes ()
173      {
174        if (exception_types == null)
175          getType();
176        return (Class<?>[]) exception_types.clone();
177      }
178    
179      /**
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.
183       *
184       * @param o the object to compare to
185       * @return <code>true</code> if they are equal; <code>false</code> if not.
186       */
187      public boolean equals (Object obj)
188      {
189        if (! (obj instanceof Constructor))
190          return false;
191        Constructor c = (Constructor) obj;
192        return declaringClass == c.declaringClass && offset == c.offset;
193      }
194    
195      /**
196       * Get the hash code for the Constructor. The Constructor hash code is the
197       * hash code of the declaring class's name.
198       *
199       * @return the hash code for the object
200       */
201      public int hashCode ()
202      {
203        return declaringClass.getName().hashCode();
204      }
205    
206      /**
207       * Get a String representation of the Constructor. A Constructor's String
208       * representation is "&lt;modifier&gt; &lt;classname&gt;(&lt;paramtypes&gt;)
209       * throws &lt;exceptions&gt;", 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>
213       *
214       * @return the String representation of the Constructor
215       */
216      public String toString()
217      {
218        if (parameter_types == null)
219          getType ();
220        StringBuffer b = new StringBuffer ();
221        int mods = getModifiers();
222        if (mods != 0)
223          {
224            Modifier.toString(mods, b);
225            b.append(" ");
226          }
227        Method.appendClassName (b, declaringClass);
228        b.append("(");
229        for (int i = 0; i < parameter_types.length; ++i)
230          {
231            Method.appendClassName (b, parameter_types[i]);
232            if (i < parameter_types.length - 1)
233              b.append(",");
234          }
235        b.append(")");
236        return b.toString();
237      }
238    
239      static <X extends GenericDeclaration>
240      void addTypeParameters(StringBuilder sb, TypeVariable<X>[] typeArgs)
241      {
242        if (typeArgs.length == 0)
243          return;
244        sb.append('<');
245        for (int i = 0; i < typeArgs.length; ++i)
246          {
247            if (i > 0)
248              sb.append(',');
249            sb.append(typeArgs[i]);
250          }
251        sb.append("> ");
252      }
253    
254      public String toGenericString()
255      {
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)
262          {
263            sb.append(types[0]);
264            for (int i = 1; i < types.length; ++i)
265              sb.append(',').append(types[i]);
266          }
267        sb.append(')');
268        types = getGenericExceptionTypes();
269        if (types.length > 0)
270          {
271            sb.append(" throws ").append(types[0]);
272            for (int i = 1; i < types.length; i++)
273              sb.append(',').append(types[i]);
274          }
275        return sb.toString();
276      }
277    
278      /**
279       * Create a new instance by invoking the constructor. Arguments are
280       * automatically unwrapped and widened, if needed.<p>
281       *
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>
285       *
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>
291       *
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>.
295       *
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
302       *         conversion
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
307       */
308      public native T newInstance (Object... args)
309        throws InstantiationException, IllegalAccessException,
310        IllegalArgumentException, InvocationTargetException;
311    
312      /**
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
316       * variables.
317       *
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.
322       * @since 1.5
323       */
324      public TypeVariable<Constructor<T>>[] getTypeParameters()
325      {
326        String sig = getSignature();
327        if (sig == null)
328          return new TypeVariable[0];
329        MethodSignatureParser p = new MethodSignatureParser(this, sig);
330        return p.getTypeParameters();
331      }
332    
333      /**
334       * Return the String in the Signature attribute for this constructor. If there
335       * is no Signature attribute, return null.
336       */
337      private native String getSignature();
338    
339      /**
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
343       * exceptions.
344       *
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.
349       * @since 1.5
350       */
351      public Type[] getGenericExceptionTypes()
352      {
353        String sig = getSignature();
354        if (sig == null)
355          return getExceptionTypes();
356        MethodSignatureParser p = new MethodSignatureParser(this, sig);
357        return p.getGenericExceptionTypes();
358      }
359    
360      /**
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
364       * parameters.
365       *
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.
370       * @since 1.5
371       */
372      public Type[] getGenericParameterTypes()
373      {
374        String sig = getSignature();
375        if (sig == null)
376          return getParameterTypes();
377        MethodSignatureParser p = new MethodSignatureParser(this, sig);
378        return p.getGenericParameterTypes();
379      }
380    
381      public <T extends Annotation> T getAnnotation(Class<T> annoClass)
382      {
383        Annotation[] annos = getDeclaredAnnotations();
384        for (int i = 0; i < annos.length; ++i)
385          if (annos[i].annotationType() == annoClass)
386            return (T) annos[i];
387        return null;
388      }
389    
390      public Annotation[] getDeclaredAnnotations()
391      {
392        Annotation[] result = getDeclaredAnnotationsInternal();
393        if (result == null)
394          result = new Annotation[0];
395        return result;
396      }
397    
398      public Annotation[][] getParameterAnnotations()
399      {
400        // FIXME: should check that we have the right number
401        // of parameters ...?
402        Annotation[][] result = getParameterAnnotationsInternal();
403        if (result == null)
404          result = new Annotation[0][0];
405        return result;
406      }
407    
408      private native Annotation[] getDeclaredAnnotationsInternal();
409      private native Annotation[][] getParameterAnnotationsInternal();
410    
411      // Update cached values from method descriptor in class.
412      private native void getType ();
413    
414      // Declaring class.
415      private Class<T> declaringClass;
416    
417      // Exception types.
418      private Class[] exception_types;
419      // Parameter types.
420      private Class[] parameter_types;
421    
422      // Offset in bytes from the start of declaringClass's methods array.
423      private int offset;
424    }