Source for java.lang.reflect.Constructor

   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: 
  43: import gnu.java.lang.reflect.MethodSignatureParser;
  44: 
  45: import java.lang.annotation.Annotation;
  46: import java.util.Arrays;
  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 Class<T> clazz;
  86:   private int slot;
  87:   
  88:   private static final int CONSTRUCTOR_MODIFIERS
  89:     = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
  90: 
  91:   /**
  92:    * This class is uninstantiable except from native code.
  93:    */
  94:   private Constructor(Class declaringClass,int slot)
  95:   {
  96:     this.clazz = declaringClass;
  97:     this.slot = slot;
  98:   }
  99: 
 100:   private Constructor()
 101:   {
 102:   }
 103: 
 104:   /**
 105:    * Gets the class that declared this constructor.
 106:    * @return the class that declared this member
 107:    */
 108:   public Class<T> getDeclaringClass()
 109:   {
 110:     return clazz;
 111:   }
 112: 
 113:   /**
 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
 117:    */
 118:   public String getName()
 119:   {
 120:     return getDeclaringClass().getName();
 121:   }
 122: 
 123:   /**
 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
 127:    */
 128:   private native int getModifiersInternal();
 129: 
 130:   /**
 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.
 134:    *
 135:    * @return an integer representing the modifiers to this Member
 136:    * @see Modifier
 137:    */
 138:   public int getModifiers()
 139:   {
 140:     return getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
 141:   }
 142: 
 143:   /**
 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.
 147:    * @since 1.5
 148:    */
 149:   public boolean isSynthetic()
 150:   {
 151:     return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
 152:   }
 153: 
 154:   /**
 155:    * Return true if this is a varargs constructor, that is if
 156:    * the constructor takes a variable number of arguments.
 157:    * @since 1.5
 158:    */
 159:   public boolean isVarArgs()
 160:   {
 161:     return (getModifiersInternal() & Modifier.VARARGS) != 0;
 162:   }
 163: 
 164:   /**
 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).
 167:    *
 168:    * @return a list of the types of the constructor's parameters
 169:    */
 170:   public native Class<?>[] getParameterTypes();
 171: 
 172:   /**
 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
 175:    * (not null).
 176:    *
 177:    * @return a list of the types in the constructor's throws clause
 178:    */
 179:   public native Class<?>[] getExceptionTypes();
 180: 
 181:   /**
 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.
 187:    *
 188:    * @param o the object to compare to
 189:    * @return <code>true</code> if they are equal; <code>false</code> if not.
 190:    */
 191:   public boolean equals(Object o)
 192:   {
 193:     if (!(o instanceof Constructor))
 194:       return false;
 195:     Constructor that = (Constructor)o; 
 196:     if (this.getDeclaringClass() != that.getDeclaringClass())
 197:       return false;
 198:     if (!Arrays.equals(this.getParameterTypes(), that.getParameterTypes()))
 199:       return false;
 200:     return true;
 201:   }
 202: 
 203:   /**
 204:    * Get the hash code for the Constructor. The Constructor hash code is the
 205:    * hash code of the declaring class's name.
 206:    *
 207:    * @return the hash code for the object
 208:    */
 209:   public int hashCode()
 210:   {
 211:     return getDeclaringClass().getName().hashCode();
 212:   }
 213: 
 214:   /**
 215:    * Get a String representation of the Constructor. A Constructor's String
 216:    * representation is "&lt;modifier&gt; &lt;classname&gt;(&lt;paramtypes&gt;)
 217:    * throws &lt;exceptions&gt;", 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>
 221:    *
 222:    * @return the String representation of the Constructor
 223:    */
 224:   public String toString()
 225:   {
 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();
 231:     if (c.length > 0)
 232:       {
 233:         sb.append(ClassHelper.getUserName(c[0]));
 234:         for (int i = 1; i < c.length; i++)
 235:           sb.append(',').append(ClassHelper.getUserName(c[i]));
 236:       }
 237:     sb.append(')');
 238:     c = getExceptionTypes();
 239:     if (c.length > 0)
 240:       {
 241:         sb.append(" throws ").append(c[0].getName());
 242:         for (int i = 1; i < c.length; i++)
 243:           sb.append(',').append(c[i].getName());
 244:       }
 245:     return sb.toString();
 246:   }
 247: 
 248:   static <X extends GenericDeclaration>
 249:   void addTypeParameters(StringBuilder sb, TypeVariable<X>[] typeArgs)
 250:   {
 251:     if (typeArgs.length == 0)
 252:       return;
 253:     sb.append('<');
 254:     for (int i = 0; i < typeArgs.length; ++i)
 255:       {
 256:         if (i > 0)
 257:           sb.append(',');
 258:         sb.append(typeArgs[i]);
 259:       }
 260:     sb.append("> ");
 261:   }
 262: 
 263:   public String toGenericString()
 264:   {
 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)
 271:       {
 272:         sb.append(types[0]);
 273:         for (int i = 1; i < types.length; ++i)
 274:           sb.append(',').append(types[i]);
 275:       }
 276:     sb.append(')');
 277:     types = getGenericExceptionTypes();
 278:     if (types.length > 0)
 279:       {
 280:         sb.append(" throws ").append(types[0]);
 281:         for (int i = 1; i < types.length; i++)
 282:           sb.append(',').append(types[i]);
 283:       }
 284:     return sb.toString();
 285:   }
 286: 
 287:   /**
 288:    * Create a new instance by invoking the constructor. Arguments are
 289:    * automatically unwrapped and widened, if needed.<p>
 290:    *
 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>
 294:    *
 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>
 300:    *
 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>.
 304:    *
 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
 311:    *         conversion
 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
 316:    */
 317:   public T newInstance(Object... args)
 318:     throws InstantiationException, IllegalAccessException,
 319:            InvocationTargetException
 320:   {
 321:     return constructNative(args, clazz, slot);
 322:   }
 323: 
 324:   private native T constructNative(Object[] args, Class declaringClass,
 325:                    int slot)
 326:     throws InstantiationException, IllegalAccessException,
 327:            InvocationTargetException;
 328: 
 329:   /**
 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
 333:    * variables.
 334:    *
 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.
 339:    * @since 1.5
 340:    */
 341:   public TypeVariable<Constructor<T>>[] getTypeParameters()
 342:   {
 343:     String sig = getSignature();
 344:     if (sig == null)
 345:       return new TypeVariable[0];
 346:     MethodSignatureParser p = new MethodSignatureParser(this, sig);
 347:     return p.getTypeParameters();
 348:   }
 349: 
 350:   /**
 351:    * Return the String in the Signature attribute for this constructor. If there
 352:    * is no Signature attribute, return null.
 353:    */
 354:   private native String getSignature();
 355: 
 356:   /**
 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
 360:    * exceptions.
 361:    *
 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.
 366:    * @since 1.5
 367:    */
 368:   public Type[] getGenericExceptionTypes()
 369:   {
 370:     String sig = getSignature();
 371:     if (sig == null)
 372:       return getExceptionTypes();
 373:     MethodSignatureParser p = new MethodSignatureParser(this, sig);
 374:     return p.getGenericExceptionTypes();
 375:   }
 376: 
 377:   /**
 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
 381:    * parameters.
 382:    *
 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.
 387:    * @since 1.5
 388:    */
 389:   public Type[] getGenericParameterTypes()
 390:   {
 391:     String sig = getSignature();
 392:     if (sig == null)
 393:       return getParameterTypes();
 394:     MethodSignatureParser p = new MethodSignatureParser(this, sig);
 395:     return p.getGenericParameterTypes();
 396:   }
 397: 
 398:   /**
 399:    * <p>
 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.
 407:    * </p>
 408:    * <p>
 409:    * The returned annotations are serialized.  Changing the annotations has
 410:    * no affect on the return value of future calls to this method.
 411:    * </p>
 412:    * 
 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.
 416:    * @since 1.5
 417:    */
 418:   public native Annotation[][] getParameterAnnotations();
 419: 
 420: }