Frames | No Frames |
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. 4: 5: This file is part of GNU Classpath. 6: 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) 10: any later version. 11: 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. 16: 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 20: 02110-1301 USA. 21: 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 25: combination. 26: 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. */ 38: 39: 40: package java.lang.reflect; 41: 42: import gnu.java.lang.reflect.MethodSignatureParser; 43: 44: /** 45: * The Constructor class represents a constructor of a class. It also allows 46: * dynamic creation of an object, via reflection. Invocation on Constructor 47: * objects knows how to do widening conversions, but throws 48: * {@link IllegalArgumentException} if a narrowing conversion would be 49: * necessary. You can query for information on this Constructor regardless 50: * of location, but construction access may be limited by Java language 51: * access controls. If you can't do it in the compiler, you can't normally 52: * do it here either.<p> 53: * 54: * <B>Note:</B> This class returns and accepts types as Classes, even 55: * primitive types; there are Class types defined that represent each 56: * different primitive type. They are <code>java.lang.Boolean.TYPE, 57: * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class, 58: * byte.class</code>, etc. These are not to be confused with the 59: * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are 60: * real classes.<p> 61: * 62: * Also note that this is not a serializable class. It is entirely feasible 63: * to make it serializable using the Externalizable interface, but this is 64: * on Sun, not me. 65: * 66: * @author John Keiser 67: * @author Eric Blake <ebb9@email.byu.edu> 68: * @author Tom Tromey <tromey@redhat.com> 69: * @see Member 70: * @see Class 71: * @see java.lang.Class#getConstructor(Class[]) 72: * @see java.lang.Class#getDeclaredConstructor(Class[]) 73: * @see java.lang.Class#getConstructors() 74: * @see java.lang.Class#getDeclaredConstructors() 75: * @since 1.1 76: * @status updated to 1.4 77: */ 78: public final class Constructor extends AccessibleObject 79: implements Member, GenericDeclaration 80: { 81: private static final int CONSTRUCTOR_MODIFIERS 82: = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC; 83: 84: /** 85: * This class is uninstantiable except from native code. 86: */ 87: private Constructor () 88: { 89: } 90: 91: /** 92: * Gets the class that declared this constructor. 93: * @return the class that declared this member 94: */ 95: public Class getDeclaringClass() 96: { 97: return declaringClass; 98: } 99: 100: /** 101: * Gets the name of this constructor (the non-qualified name of the class 102: * it was declared in). 103: * @return the name of this constructor 104: */ 105: public String getName() 106: { 107: return declaringClass.getName(); 108: } 109: 110: /** 111: * Return the raw modifiers for this constructor. In particular 112: * this will include the synthetic and varargs bits. 113: * @return the constructor's modifiers 114: */ 115: private native int getModifiersInternal(); 116: 117: /** 118: * Gets the modifiers this constructor uses. Use the <code>Modifier</code> 119: * class to interpret the values. A constructor can only have a subset of the 120: * following modifiers: public, private, protected. 121: * 122: * @return an integer representing the modifiers to this Member 123: * @see Modifier 124: */ 125: public int getModifiers () 126: { 127: return getModifiersInternal() & CONSTRUCTOR_MODIFIERS; 128: } 129: 130: /** 131: * Return true if this constructor is synthetic, false otherwise. 132: * A synthetic member is one which is created by the compiler, 133: * and which does not appear in the user's source code. 134: * @since 1.5 135: */ 136: public boolean isSynthetic() 137: { 138: return (getModifiersInternal() & Modifier.SYNTHETIC) != 0; 139: } 140: 141: /** 142: * Return true if this is a varargs constructor, that is if 143: * the constructor takes a variable number of arguments. 144: * @since 1.5 145: */ 146: public boolean isVarArgs() 147: { 148: return (getModifiersInternal() & Modifier.VARARGS) != 0; 149: } 150: 151: /** 152: * Get the parameter list for this constructor, in declaration order. If the 153: * constructor takes no parameters, returns a 0-length array (not null). 154: * 155: * @return a list of the types of the constructor's parameters 156: */ 157: public Class[] getParameterTypes () 158: { 159: if (parameter_types == null) 160: getType (); 161: return (Class[]) parameter_types.clone(); 162: } 163: 164: /** 165: * Get the exception types this constructor says it throws, in no particular 166: * order. If the constructor has no throws clause, returns a 0-length array 167: * (not null). 168: * 169: * @return a list of the types in the constructor's throws clause 170: */ 171: public Class[] getExceptionTypes () 172: { 173: if (exception_types == null) 174: getType(); 175: return (Class[]) exception_types.clone(); 176: } 177: 178: /** 179: * Compare two objects to see if they are semantically equivalent. 180: * Two Constructors are semantically equivalent if they have the same 181: * declaring class and the same parameter list. 182: * 183: * @param o the object to compare to 184: * @return <code>true</code> if they are equal; <code>false</code> if not. 185: */ 186: public boolean equals (Object obj) 187: { 188: if (! (obj instanceof Constructor)) 189: return false; 190: Constructor c = (Constructor) obj; 191: return declaringClass == c.declaringClass && offset == c.offset; 192: } 193: 194: /** 195: * Get the hash code for the Constructor. The Constructor hash code is the 196: * hash code of the declaring class's name. 197: * 198: * @return the hash code for the object 199: */ 200: public int hashCode () 201: { 202: return declaringClass.getName().hashCode(); 203: } 204: 205: /** 206: * Get a String representation of the Constructor. A Constructor's String 207: * representation is "<modifier> <classname>(<paramtypes>) 208: * throws <exceptions>", where everything after ')' is omitted if 209: * there are no exceptions.<br> Example: 210: * <code>public java.io.FileInputStream(java.lang.Runnable) 211: * throws java.io.FileNotFoundException</code> 212: * 213: * @return the String representation of the Constructor 214: */ 215: public String toString() 216: { 217: if (parameter_types == null) 218: getType (); 219: StringBuffer b = new StringBuffer (); 220: int mods = getModifiers(); 221: if (mods != 0) 222: { 223: Modifier.toString(mods, b); 224: b.append(" "); 225: } 226: Method.appendClassName (b, declaringClass); 227: b.append("("); 228: for (int i = 0; i < parameter_types.length; ++i) 229: { 230: Method.appendClassName (b, parameter_types[i]); 231: if (i < parameter_types.length - 1) 232: b.append(","); 233: } 234: b.append(")"); 235: return b.toString(); 236: } 237: 238: /* FIXME[GENERICS]: Add X extends GenericDeclaration and TypeVariable<X> */ 239: static void addTypeParameters(StringBuilder sb, TypeVariable[] typeArgs) 240: { 241: if (typeArgs.length == 0) 242: return; 243: sb.append('<'); 244: for (int i = 0; i < typeArgs.length; ++i) 245: { 246: if (i > 0) 247: sb.append(','); 248: sb.append(typeArgs[i]); 249: } 250: sb.append("> "); 251: } 252: 253: public String toGenericString() 254: { 255: StringBuilder sb = new StringBuilder(128); 256: Modifier.toString(getModifiers(), sb).append(' '); 257: addTypeParameters(sb, getTypeParameters()); 258: sb.append(getDeclaringClass().getName()).append('('); 259: Type[] types = getGenericParameterTypes(); 260: if (types.length > 0) 261: { 262: sb.append(types[0]); 263: for (int i = 1; i < types.length; ++i) 264: sb.append(',').append(types[i]); 265: } 266: sb.append(')'); 267: types = getGenericExceptionTypes(); 268: if (types.length > 0) 269: { 270: sb.append(" throws ").append(types[0]); 271: for (int i = 1; i < types.length; i++) 272: sb.append(',').append(types[i]); 273: } 274: return sb.toString(); 275: } 276: 277: /** 278: * Create a new instance by invoking the constructor. Arguments are 279: * automatically unwrapped and widened, if needed.<p> 280: * 281: * If this class is abstract, you will get an 282: * <code>InstantiationException</code>. If the constructor takes 0 283: * arguments, you may use null or a 0-length array for <code>args</code>.<p> 284: * 285: * If this Constructor enforces access control, your runtime context is 286: * evaluated, and you may have an <code>IllegalAccessException</code> if 287: * you could not create this object in similar compiled code. If the class 288: * is uninitialized, you trigger class initialization, which may end in a 289: * <code>ExceptionInInitializerError</code>.<p> 290: * 291: * Then, the constructor is invoked. If it completes normally, the return 292: * value will be the new object. If it completes abruptly, the exception is 293: * wrapped in an <code>InvocationTargetException</code>. 294: * 295: * @param args the arguments to the constructor 296: * @return the newly created object 297: * @throws IllegalAccessException if the constructor could not normally be 298: * called by the Java code (i.e. it is not public) 299: * @throws IllegalArgumentException if the number of arguments is incorrect; 300: * or if the arguments types are wrong even with a widening 301: * conversion 302: * @throws InstantiationException if the class is abstract 303: * @throws InvocationTargetException if the constructor throws an exception 304: * @throws ExceptionInInitializerError if construction triggered class 305: * initialization, which then failed 306: */ 307: public native Object newInstance (Object[] args) 308: throws InstantiationException, IllegalAccessException, 309: IllegalArgumentException, InvocationTargetException; 310: 311: /** 312: * Returns an array of <code>TypeVariable</code> objects that represents 313: * the type variables declared by this constructor, in declaration order. 314: * An array of size zero is returned if this constructor has no type 315: * variables. 316: * 317: * @return the type variables associated with this constructor. 318: * @throws GenericSignatureFormatError if the generic signature does 319: * not conform to the format specified in the Virtual Machine 320: * specification, version 3. 321: * @since 1.5 322: */ 323: /* FIXME[GENERICS]: Add <Constructor<T>> */ 324: public TypeVariable[] 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 String getSignature() 338: { 339: // FIXME: libgcj doesn't record this information yet. 340: return null; 341: } 342: 343: /** 344: * Returns an array of <code>Type</code> objects that represents 345: * the exception types declared by this constructor, in declaration order. 346: * An array of size zero is returned if this constructor declares no 347: * exceptions. 348: * 349: * @return the exception types declared by this constructor. 350: * @throws GenericSignatureFormatError if the generic signature does 351: * not conform to the format specified in the Virtual Machine 352: * specification, version 3. 353: * @since 1.5 354: */ 355: public Type[] getGenericExceptionTypes() 356: { 357: String sig = getSignature(); 358: if (sig == null) 359: return getExceptionTypes(); 360: MethodSignatureParser p = new MethodSignatureParser(this, sig); 361: return p.getGenericExceptionTypes(); 362: } 363: 364: /** 365: * Returns an array of <code>Type</code> objects that represents 366: * the parameter list for this constructor, in declaration order. 367: * An array of size zero is returned if this constructor takes no 368: * parameters. 369: * 370: * @return a list of the types of the constructor's parameters 371: * @throws GenericSignatureFormatError if the generic signature does 372: * not conform to the format specified in the Virtual Machine 373: * specification, version 3. 374: * @since 1.5 375: */ 376: public Type[] getGenericParameterTypes() 377: { 378: String sig = getSignature(); 379: if (sig == null) 380: return getParameterTypes(); 381: MethodSignatureParser p = new MethodSignatureParser(this, sig); 382: return p.getGenericParameterTypes(); 383: } 384: 385: // Update cached values from method descriptor in class. 386: private native void getType (); 387: 388: // Declaring class. 389: private Class declaringClass; 390: 391: // Exception types. 392: private Class[] exception_types; 393: // Parameter types. 394: private Class[] parameter_types; 395: 396: // Offset in bytes from the start of declaringClass's methods array. 397: private int offset; 398: }