001 /* java.lang.reflect.Constructor - reflection of Java constructors 002 Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 003 Free Software Foundation, Inc. 004 005 This file is part of GNU Classpath. 006 007 GNU Classpath is free software; you can redistribute it and/or modify 008 it under the terms of the GNU General Public License as published by 009 the Free Software Foundation; either version 2, or (at your option) 010 any later version. 011 012 GNU Classpath is distributed in the hope that it will be useful, but 013 WITHOUT ANY WARRANTY; without even the implied warranty of 014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 General Public License for more details. 016 017 You should have received a copy of the GNU General Public License 018 along with GNU Classpath; see the file COPYING. If not, write to the 019 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 020 02110-1301 USA. 021 022 Linking this library statically or dynamically with other modules is 023 making a combined work based on this library. Thus, the terms and 024 conditions of the GNU General Public License cover the whole 025 combination. 026 027 As a special exception, the copyright holders of this library give you 028 permission to link this library with independent modules to produce an 029 executable, regardless of the license terms of these independent 030 modules, and to copy and distribute the resulting executable under 031 terms of your choice, provided that you also meet, for each linked 032 independent module, the terms and conditions of the license of that 033 module. An independent module is a module which is not derived from 034 or based on this library. If you modify this library, you may extend 035 this exception to your version of the library, but you are not 036 obligated to do so. If you do not wish to do so, delete this 037 exception statement from your version. */ 038 039 040 package java.lang.reflect; 041 042 import gnu.java.lang.reflect.MethodSignatureParser; 043 import java.lang.annotation.Annotation; 044 045 /** 046 * The Constructor class represents a constructor of a class. It also allows 047 * dynamic creation of an object, via reflection. Invocation on Constructor 048 * objects knows how to do widening conversions, but throws 049 * {@link IllegalArgumentException} if a narrowing conversion would be 050 * necessary. You can query for information on this Constructor regardless 051 * of location, but construction access may be limited by Java language 052 * access controls. If you can't do it in the compiler, you can't normally 053 * do it here either.<p> 054 * 055 * <B>Note:</B> This class returns and accepts types as Classes, even 056 * primitive types; there are Class types defined that represent each 057 * different primitive type. They are <code>java.lang.Boolean.TYPE, 058 * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class, 059 * byte.class</code>, etc. These are not to be confused with the 060 * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are 061 * real classes.<p> 062 * 063 * Also note that this is not a serializable class. It is entirely feasible 064 * to make it serializable using the Externalizable interface, but this is 065 * on Sun, not me. 066 * 067 * @author John Keiser 068 * @author Eric Blake <ebb9@email.byu.edu> 069 * @author Tom Tromey <tromey@redhat.com> 070 * @see Member 071 * @see Class 072 * @see java.lang.Class#getConstructor(Class[]) 073 * @see java.lang.Class#getDeclaredConstructor(Class[]) 074 * @see java.lang.Class#getConstructors() 075 * @see java.lang.Class#getDeclaredConstructors() 076 * @since 1.1 077 * @status updated to 1.4 078 */ 079 public final class Constructor<T> extends AccessibleObject 080 implements Member, GenericDeclaration 081 { 082 private static final int CONSTRUCTOR_MODIFIERS 083 = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC; 084 085 /** 086 * This class is uninstantiable except from native code. 087 */ 088 private Constructor () 089 { 090 } 091 092 /** 093 * Gets the class that declared this constructor. 094 * @return the class that declared this member 095 */ 096 public Class<T> getDeclaringClass () 097 { 098 return declaringClass; 099 } 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 }