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