GNU Classpath (0.98) | |
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: import gnu.java.lang.CPStringBuilder; 43: 44: import gnu.java.lang.reflect.MethodSignatureParser; 45: 46: import java.lang.annotation.Annotation; 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 static final int CONSTRUCTOR_MODIFIERS 86: = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC; 87: 88: private MethodSignatureParser p; 89: 90: VMConstructor cons; 91: 92: /** 93: * This class is uninstantiable outside this package. 94: */ 95: Constructor(VMConstructor cons) 96: { 97: this.cons = cons; 98: cons.cons = this; 99: } 100: 101: private Constructor() 102: { 103: } 104: 105: /** 106: * Gets the class that declared this constructor. 107: * @return the class that declared this member 108: */ 109: public Class<T> getDeclaringClass() 110: { 111: // Inescapable as the VM layer is 1.4 based. 112: @SuppressWarnings("unchecked") 113: Class<T> declClass = (Class<T>) cons.getDeclaringClass(); 114: return declClass; 115: } 116: 117: /** 118: * Gets the name of this constructor (the non-qualified name of the class 119: * it was declared in). 120: * @return the name of this constructor 121: */ 122: public String getName() 123: { 124: return cons.getDeclaringClass().getName(); 125: } 126: 127: /** 128: * Gets the modifiers this constructor uses. Use the <code>Modifier</code> 129: * class to interpret the values. A constructor can only have a subset of the 130: * following modifiers: public, private, protected. 131: * 132: * @return an integer representing the modifiers to this Member 133: * @see Modifier 134: */ 135: public int getModifiers() 136: { 137: return cons.getModifiersInternal() & CONSTRUCTOR_MODIFIERS; 138: } 139: 140: /** 141: * Return true if this constructor is synthetic, false otherwise. 142: * A synthetic member is one which is created by the compiler, 143: * and which does not appear in the user's source code. 144: * @since 1.5 145: */ 146: public boolean isSynthetic() 147: { 148: return (cons.getModifiersInternal() & Modifier.SYNTHETIC) != 0; 149: } 150: 151: /** 152: * Return true if this is a varargs constructor, that is if 153: * the constructor takes a variable number of arguments. 154: * @since 1.5 155: */ 156: public boolean isVarArgs() 157: { 158: return (cons.getModifiersInternal() & Modifier.VARARGS) != 0; 159: } 160: 161: /** 162: * Get the parameter list for this constructor, in declaration order. If the 163: * constructor takes no parameters, returns a 0-length array (not null). 164: * 165: * @return a list of the types of the constructor's parameters 166: */ 167: public Class<?>[] getParameterTypes() 168: { 169: return (Class<?>[]) cons.getParameterTypes(); 170: } 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 Class<?>[] getExceptionTypes() 180: { 181: return (Class<?>[]) cons.getExceptionTypes(); 182: } 183: 184: /** 185: * Compare two objects to see if they are semantically equivalent. 186: * Two Constructors are semantically equivalent if they have the same 187: * declaring class and the same parameter list. This ignores different 188: * exception clauses, but since you can't create a Method except through the 189: * VM, this is just the == relation. 190: * 191: * @param o the object to compare to 192: * @return <code>true</code> if they are equal; <code>false</code> if not. 193: */ 194: public boolean equals(Object o) 195: { 196: return cons.equals(o); 197: } 198: 199: /** 200: * Get the hash code for the Constructor. The Constructor hash code is the 201: * hash code of the declaring class's name. 202: * 203: * @return the hash code for the object 204: */ 205: public int hashCode() 206: { 207: return getName().hashCode(); 208: } 209: 210: /** 211: * Get a String representation of the Constructor. A Constructor's String 212: * representation is "<modifier> <classname>(<paramtypes>) 213: * throws <exceptions>", where everything after ')' is omitted if 214: * there are no exceptions.<br> Example: 215: * <code>public java.io.FileInputStream(java.lang.Runnable) 216: * throws java.io.FileNotFoundException</code> 217: * 218: * @return the String representation of the Constructor 219: */ 220: public String toString() 221: { 222: // 128 is a reasonable buffer initial size for constructor 223: CPStringBuilder sb = new CPStringBuilder(128); 224: Modifier.toString(getModifiers(), sb).append(' '); 225: sb.append(getDeclaringClass().getName()).append('('); 226: Class[] c = getParameterTypes(); 227: if (c.length > 0) 228: { 229: sb.append(ClassHelper.getUserName(c[0])); 230: for (int i = 1; i < c.length; i++) 231: sb.append(',').append(ClassHelper.getUserName(c[i])); 232: } 233: sb.append(')'); 234: c = getExceptionTypes(); 235: if (c.length > 0) 236: { 237: sb.append(" throws ").append(c[0].getName()); 238: for (int i = 1; i < c.length; i++) 239: sb.append(',').append(c[i].getName()); 240: } 241: return sb.toString(); 242: } 243: 244: static <X extends GenericDeclaration> 245: void addTypeParameters(CPStringBuilder sb, TypeVariable<X>[] typeArgs) 246: { 247: if (typeArgs.length == 0) 248: return; 249: sb.append('<'); 250: for (int i = 0; i < typeArgs.length; ++i) 251: { 252: if (i > 0) 253: sb.append(','); 254: sb.append(typeArgs[i]); 255: } 256: sb.append("> "); 257: } 258: 259: public String toGenericString() 260: { 261: CPStringBuilder sb = new CPStringBuilder(128); 262: Modifier.toString(getModifiers(), sb).append(' '); 263: addTypeParameters(sb, getTypeParameters()); 264: sb.append(getDeclaringClass().getName()).append('('); 265: Type[] types = getGenericParameterTypes(); 266: if (types.length > 0) 267: { 268: sb.append(types[0]); 269: for (int i = 1; i < types.length; ++i) 270: sb.append(',').append(types[i]); 271: } 272: sb.append(')'); 273: types = getGenericExceptionTypes(); 274: if (types.length > 0) 275: { 276: sb.append(" throws ").append(types[0]); 277: for (int i = 1; i < types.length; i++) 278: sb.append(',').append(types[i]); 279: } 280: return sb.toString(); 281: } 282: 283: /** 284: * Create a new instance by invoking the constructor. Arguments are 285: * automatically unwrapped and widened, if needed.<p> 286: * 287: * If this class is abstract, you will get an 288: * <code>InstantiationException</code>. If the constructor takes 0 289: * arguments, you may use null or a 0-length array for <code>args</code>.<p> 290: * 291: * If this Constructor enforces access control, your runtime context is 292: * evaluated, and you may have an <code>IllegalAccessException</code> if 293: * you could not create this object in similar compiled code. If the class 294: * is uninitialized, you trigger class initialization, which may end in a 295: * <code>ExceptionInInitializerError</code>.<p> 296: * 297: * Then, the constructor is invoked. If it completes normally, the return 298: * value will be the new object. If it completes abruptly, the exception is 299: * wrapped in an <code>InvocationTargetException</code>. 300: * 301: * @param args the arguments to the constructor 302: * @return the newly created object 303: * @throws IllegalAccessException if the constructor could not normally be 304: * called by the Java code (i.e. it is not public) 305: * @throws IllegalArgumentException if the number of arguments is incorrect; 306: * or if the arguments types are wrong even with a widening 307: * conversion 308: * @throws InstantiationException if the class is abstract 309: * @throws InvocationTargetException if the constructor throws an exception 310: * @throws ExceptionInInitializerError if construction triggered class 311: * initialization, which then failed 312: */ 313: public T newInstance(Object... args) 314: throws InstantiationException, IllegalAccessException, 315: InvocationTargetException 316: { 317: // Inescapable as the VM layer is 1.4 based. 318: @SuppressWarnings("unchecked") 319: T ins = (T) cons.construct(args); 320: return ins; 321: } 322: 323: /** 324: * Returns an array of <code>TypeVariable</code> objects that represents 325: * the type variables declared by this constructor, in declaration order. 326: * An array of size zero is returned if this constructor has no type 327: * variables. 328: * 329: * @return the type variables associated with this constructor. 330: * @throws GenericSignatureFormatError if the generic signature does 331: * not conform to the format specified in the Virtual Machine 332: * specification, version 3. 333: * @since 1.5 334: */ 335: public TypeVariable<Constructor<T>>[] getTypeParameters() 336: { 337: if (p == null) 338: { 339: String sig = cons.getSignature(); 340: if (sig == null) 341: return new TypeVariable[0]; 342: p = new MethodSignatureParser(this, sig); 343: } 344: return p.getTypeParameters(); 345: } 346: 347: /** 348: * Returns an array of <code>Type</code> objects that represents 349: * the exception types declared by this constructor, in declaration order. 350: * An array of size zero is returned if this constructor declares no 351: * exceptions. 352: * 353: * @return the exception types declared by this constructor. 354: * @throws GenericSignatureFormatError if the generic signature does 355: * not conform to the format specified in the Virtual Machine 356: * specification, version 3. 357: * @since 1.5 358: */ 359: public Type[] getGenericExceptionTypes() 360: { 361: if (p == null) 362: { 363: String sig = cons.getSignature(); 364: if (sig == null) 365: return getExceptionTypes(); 366: p = new MethodSignatureParser(this, sig); 367: } 368: return p.getGenericExceptionTypes(); 369: } 370: 371: /** 372: * Returns an array of <code>Type</code> objects that represents 373: * the parameter list for this constructor, in declaration order. 374: * An array of size zero is returned if this constructor takes no 375: * parameters. 376: * 377: * @return a list of the types of the constructor's parameters 378: * @throws GenericSignatureFormatError if the generic signature does 379: * not conform to the format specified in the Virtual Machine 380: * specification, version 3. 381: * @since 1.5 382: */ 383: public Type[] getGenericParameterTypes() 384: { 385: if (p == null) 386: { 387: String sig = cons.getSignature(); 388: if (sig == null) 389: return getParameterTypes(); 390: p = new MethodSignatureParser(this, sig); 391: } 392: return p.getGenericParameterTypes(); 393: } 394: 395: /** 396: * <p> 397: * Return an array of arrays representing the annotations on each 398: * of the constructor's parameters. The outer array is aligned against 399: * the parameters of the constructors and is thus equal in length to 400: * the number of parameters (thus having a length zero if there are none). 401: * Each array element in the outer array contains an inner array which 402: * holds the annotations. This array has a length of zero if the parameter 403: * has no annotations. 404: * </p> 405: * <p> 406: * The returned annotations are serialized. Changing the annotations has 407: * no affect on the return value of future calls to this method. 408: * </p> 409: * 410: * @return an array of arrays which represents the annotations used on the 411: * parameters of this constructor. The order of the array elements 412: * matches the declaration order of the parameters. 413: * @since 1.5 414: */ 415: public Annotation[][] getParameterAnnotations() 416: { 417: return cons.getParameterAnnotations(); 418: } 419: 420: /** 421: * Returns the element's annotation for the specified annotation type, 422: * or <code>null</code> if no such annotation exists. 423: * 424: * @param annotationClass the type of annotation to look for. 425: * @return this element's annotation for the specified type, or 426: * <code>null</code> if no such annotation exists. 427: * @throws NullPointerException if the annotation class is <code>null</code>. 428: */ 429: public <T extends Annotation> T getAnnotation(Class<T> annotationClass) 430: { 431: // Inescapable as the VM layer is 1.4 based. 432: @SuppressWarnings("unchecked") 433: T ann = (T) cons.getAnnotation(annotationClass); 434: return ann; 435: } 436: 437: /** 438: * Returns all annotations directly defined by the element. If there are 439: * no annotations directly associated with the element, then a zero-length 440: * array will be returned. The returned array may be modified by the client 441: * code, but this will have no effect on the annotation content of this 442: * class, and hence no effect on the return value of this method for 443: * future callers. 444: * 445: * @return the annotations directly defined by the element. 446: * @since 1.5 447: */ 448: public Annotation[] getDeclaredAnnotations() 449: { 450: return cons.getDeclaredAnnotations(); 451: } 452: 453: }
GNU Classpath (0.98) |