GNU Classpath (0.97.2) | |
Frames | No Frames |
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 "<modifier> <classname>(<paramtypes>) 217: * throws <exceptions>", 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: }
GNU Classpath (0.97.2) |