Frames | No Frames |
1: /* java.lang.reflect.Constructor - reflection of Java constructors 2: Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 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: import java.lang.annotation.Annotation; 44: 45: /** 46: * The Constructor class represents a constructor of a class. It also allows 47: * dynamic creation of an object, via reflection. Invocation on Constructor 48: * objects knows how to do widening conversions, but throws 49: * {@link IllegalArgumentException} if a narrowing conversion would be 50: * necessary. You can query for information on this Constructor regardless 51: * of location, but construction access may be limited by Java language 52: * access controls. If you can't do it in the compiler, you can't normally 53: * do it here either.<p> 54: * 55: * <B>Note:</B> This class returns and accepts types as Classes, even 56: * primitive types; there are Class types defined that represent each 57: * different primitive type. They are <code>java.lang.Boolean.TYPE, 58: * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class, 59: * byte.class</code>, etc. These are not to be confused with the 60: * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are 61: * real classes.<p> 62: * 63: * Also note that this is not a serializable class. It is entirely feasible 64: * to make it serializable using the Externalizable interface, but this is 65: * on Sun, not me. 66: * 67: * @author John Keiser 68: * @author Eric Blake <ebb9@email.byu.edu> 69: * @author Tom Tromey <tromey@redhat.com> 70: * @see Member 71: * @see Class 72: * @see java.lang.Class#getConstructor(Class[]) 73: * @see java.lang.Class#getDeclaredConstructor(Class[]) 74: * @see java.lang.Class#getConstructors() 75: * @see java.lang.Class#getDeclaredConstructors() 76: * @since 1.1 77: * @status updated to 1.4 78: */ 79: public final class Constructor<T> extends AccessibleObject 80: implements Member, GenericDeclaration 81: { 82: private static final int CONSTRUCTOR_MODIFIERS 83: = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC; 84: 85: /** 86: * This class is uninstantiable except from native code. 87: */ 88: private Constructor () 89: { 90: } 91: 92: /** 93: * Gets the class that declared this constructor. 94: * @return the class that declared this member 95: */ 96: public Class<T> getDeclaringClass () 97: { 98: return declaringClass; 99: } 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 "<modifier> <classname>(<paramtypes>) 209: * throws <exceptions>", 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: }