1. /*
  2. * @(#)Constructor.java 1.49 04/05/04
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.lang.reflect;
  8. import sun.reflect.ConstructorAccessor;
  9. import sun.reflect.Reflection;
  10. import sun.reflect.generics.repository.ConstructorRepository;
  11. import sun.reflect.generics.factory.CoreReflectionFactory;
  12. import sun.reflect.generics.factory.GenericsFactory;
  13. import sun.reflect.generics.scope.ConstructorScope;
  14. import java.lang.annotation.Annotation;
  15. import java.util.Map;
  16. import sun.reflect.annotation.AnnotationParser;
  17. /**
  18. * <code>Constructor</code> provides information about, and access to, a single
  19. * constructor for a class.
  20. *
  21. * <p><code>Constructor</code> permits widening conversions to occur when matching the
  22. * actual parameters to newInstance() with the underlying
  23. * constructor's formal parameters, but throws an
  24. * <code>IllegalArgumentException</code> if a narrowing conversion would occur.
  25. *
  26. * @see Member
  27. * @see java.lang.Class
  28. * @see java.lang.Class#getConstructors()
  29. * @see java.lang.Class#getConstructor(Class[])
  30. * @see java.lang.Class#getDeclaredConstructors()
  31. *
  32. * @author Kenneth Russell
  33. * @author Nakul Saraiya
  34. */
  35. public final
  36. class Constructor<T> extends AccessibleObject implements
  37. GenericDeclaration,
  38. Member {
  39. private Class<T> clazz;
  40. private int slot;
  41. private Class[] parameterTypes;
  42. private Class[] exceptionTypes;
  43. private int modifiers;
  44. // Generics and annotations support
  45. private transient String signature;
  46. // generic info repository; lazily initialized
  47. private transient ConstructorRepository genericInfo;
  48. private byte[] annotations;
  49. private byte[] parameterAnnotations;
  50. // Generics infrastructure
  51. // Accessor for factory
  52. private GenericsFactory getFactory() {
  53. // create scope and factory
  54. return CoreReflectionFactory.make(this, ConstructorScope.make(this));
  55. }
  56. // Accessor for generic info repository
  57. private ConstructorRepository getGenericInfo() {
  58. // lazily initialize repository if necessary
  59. if (genericInfo == null) {
  60. // create and cache generic info repository
  61. genericInfo =
  62. ConstructorRepository.make(getSignature(),
  63. getFactory());
  64. }
  65. return genericInfo; //return cached repository
  66. }
  67. private volatile ConstructorAccessor constructorAccessor;
  68. // For sharing of ConstructorAccessors. This branching structure
  69. // is currently only two levels deep (i.e., one root Constructor
  70. // and potentially many Constructor objects pointing to it.)
  71. private Constructor<T> root;
  72. /**
  73. * Package-private constructor used by ReflectAccess to enable
  74. * instantiation of these objects in Java code from the java.lang
  75. * package via sun.reflect.LangReflectAccess.
  76. */
  77. Constructor(Class<T> declaringClass,
  78. Class[] parameterTypes,
  79. Class[] checkedExceptions,
  80. int modifiers,
  81. int slot,
  82. String signature,
  83. byte[] annotations,
  84. byte[] parameterAnnotations)
  85. {
  86. this.clazz = declaringClass;
  87. this.parameterTypes = parameterTypes;
  88. this.exceptionTypes = checkedExceptions;
  89. this.modifiers = modifiers;
  90. this.slot = slot;
  91. this.signature = signature;
  92. this.annotations = annotations;
  93. this.parameterAnnotations = parameterAnnotations;
  94. }
  95. /**
  96. * Package-private routine (exposed to java.lang.Class via
  97. * ReflectAccess) which returns a copy of this Constructor. The copy's
  98. * "root" field points to this Constructor.
  99. */
  100. Constructor<T> copy() {
  101. // This routine enables sharing of ConstructorAccessor objects
  102. // among Constructor objects which refer to the same underlying
  103. // method in the VM. (All of this contortion is only necessary
  104. // because of the "accessibility" bit in AccessibleObject,
  105. // which implicitly requires that new java.lang.reflect
  106. // objects be fabricated for each reflective call on Class
  107. // objects.)
  108. Constructor<T> res = new Constructor<T>(clazz,
  109. parameterTypes,
  110. exceptionTypes, modifiers, slot,
  111. signature,
  112. annotations,
  113. parameterAnnotations);
  114. res.root = this;
  115. // Might as well eagerly propagate this if already present
  116. res.constructorAccessor = constructorAccessor;
  117. return res;
  118. }
  119. /**
  120. * Returns the <code>Class</code> object representing the class that declares
  121. * the constructor represented by this <code>Constructor</code> object.
  122. */
  123. public Class<T> getDeclaringClass() {
  124. return clazz;
  125. }
  126. /**
  127. * Returns the name of this constructor, as a string. This is
  128. * always the same as the simple name of the constructor's declaring
  129. * class.
  130. */
  131. public String getName() {
  132. return getDeclaringClass().getName();
  133. }
  134. /**
  135. * Returns the Java language modifiers for the constructor
  136. * represented by this <code>Constructor</code> object, as an integer. The
  137. * <code>Modifier</code> class should be used to decode the modifiers.
  138. *
  139. * @see Modifier
  140. */
  141. public int getModifiers() {
  142. return modifiers;
  143. }
  144. /**
  145. * Returns an array of <tt>TypeVariable</tt> objects that represent the
  146. * type variables declared by the generic declaration represented by this
  147. * <tt>GenericDeclaration</tt> object, in declaration order. Returns an
  148. * array of length 0 if the underlying generic declaration declares no type
  149. * variables.
  150. *
  151. * @return an array of <tt>TypeVariable</tt> objects that represent
  152. * the type variables declared by this generic declaration
  153. * @throws GenericSignatureFormatError if the generic
  154. * signature of this generic declaration does not conform to
  155. * the format specified in the Java Virtual Machine Specification,
  156. * 3rd edition
  157. * @since 1.5
  158. */
  159. public TypeVariable<Constructor<T>>[] getTypeParameters() {
  160. if (getSignature() != null) {
  161. return (TypeVariable<Constructor<T>>[])getGenericInfo().getTypeParameters();
  162. } else
  163. return (TypeVariable<Constructor<T>>[])new TypeVariable[0];
  164. }
  165. /**
  166. * Returns an array of <code>Class</code> objects that represent the formal
  167. * parameter types, in declaration order, of the constructor
  168. * represented by this <code>Constructor</code> object. Returns an array of
  169. * length 0 if the underlying constructor takes no parameters.
  170. *
  171. * @return the parameter types for the constructor this object
  172. * represents
  173. */
  174. public Class<?>[] getParameterTypes() {
  175. return (Class<?>[]) parameterTypes.clone();
  176. }
  177. /**
  178. * Returns an array of <tt>Type</tt> objects that represent the formal
  179. * parameter types, in declaration order, of the method represented by
  180. * this <tt>Constructor</tt> object. Returns an array of length 0 if the
  181. * underlying method takes no parameters.
  182. *
  183. * <p>If a formal parameter type is a parameterized type,
  184. * the <tt>Type</tt> object returned for it must accurately reflect
  185. * the actual type parameters used in the source code.
  186. *
  187. * <p>If a formal parameter type is a type variable or a parameterized
  188. * type, it is created. Otherwise, it is resolved.
  189. *
  190. * @return an array of <tt>Type</tt>s that represent the formal
  191. * parameter types of the underlying method, in declaration order
  192. * @throws GenericSignatureFormatError
  193. * if the generic method signature does not conform to the format
  194. * specified in the Java Virtual Machine Specification, 3rd edition
  195. * @throws TypeNotPresentException if any of the parameter
  196. * types of the underlying method refers to a non-existent type
  197. * declaration
  198. * @throws MalformedParameterizedTypeException if any of
  199. * the underlying method's parameter types refer to a parameterized
  200. * type that cannot be instantiated for any reason
  201. * @since 1.5
  202. */
  203. public Type[] getGenericParameterTypes() {
  204. if (getSignature() != null)
  205. return getGenericInfo().getParameterTypes();
  206. else
  207. return getParameterTypes();
  208. }
  209. /**
  210. * Returns an array of <code>Class</code> objects that represent the types
  211. * of exceptions declared to be thrown by the underlying constructor
  212. * represented by this <code>Constructor</code> object. Returns an array of
  213. * length 0 if the constructor declares no exceptions in its <code>throws</code> clause.
  214. *
  215. * @return the exception types declared as being thrown by the
  216. * constructor this object represents
  217. */
  218. public Class<?>[] getExceptionTypes() {
  219. return (Class<?>[])exceptionTypes.clone();
  220. }
  221. /**
  222. * Returns an array of <tt>Type</tt> objects that represent the
  223. * exceptions declared to be thrown by this <tt>Constructor</tt> object.
  224. * Returns an array of length 0 if the underlying method declares
  225. * no exceptions in its <tt>throws</tt> clause.
  226. *
  227. * <p>If an exception type is a parameterized type, the <tt>Type</tt>
  228. * object returned for it must accurately reflect the actual type
  229. * parameters used in the source code.
  230. *
  231. * <p>If an exception type is a type variable or a parameterized
  232. * type, it is created. Otherwise, it is resolved.
  233. *
  234. * @return an array of Types that represent the exception types
  235. * thrown by the underlying method
  236. * @throws GenericSignatureFormatError
  237. * if the generic method signature does not conform to the format
  238. * specified in the Java Virtual Machine Specification, 3rd edition
  239. * @throws TypeNotPresentException if the underlying method's
  240. * <tt>throws</tt> clause refers to a non-existent type declaration
  241. * @throws MalformedParameterizedTypeException if
  242. * the underlying method's <tt>throws</tt> clause refers to a
  243. * parameterized type that cannot be instantiated for any reason
  244. * @since 1.5
  245. */
  246. public Type[] getGenericExceptionTypes() {
  247. Type[] result;
  248. if (getSignature() != null &&
  249. ( (result = getGenericInfo().getExceptionTypes()).length > 0 ))
  250. return result;
  251. else
  252. return getExceptionTypes();
  253. }
  254. /**
  255. * Compares this <code>Constructor</code> against the specified object.
  256. * Returns true if the objects are the same. Two <code>Constructor</code> objects are
  257. * the same if they were declared by the same class and have the
  258. * same formal parameter types.
  259. */
  260. public boolean equals(Object obj) {
  261. if (obj != null && obj instanceof Constructor) {
  262. Constructor other = (Constructor)obj;
  263. if (getDeclaringClass() == other.getDeclaringClass()) {
  264. /* Avoid unnecessary cloning */
  265. Class[] params1 = parameterTypes;
  266. Class[] params2 = other.parameterTypes;
  267. if (params1.length == params2.length) {
  268. for (int i = 0; i < params1.length; i++) {
  269. if (params1[i] != params2[i])
  270. return false;
  271. }
  272. return true;
  273. }
  274. }
  275. }
  276. return false;
  277. }
  278. /**
  279. * Returns a hashcode for this <code>Constructor</code>. The hashcode is
  280. * the same as the hashcode for the underlying constructor's
  281. * declaring class name.
  282. */
  283. public int hashCode() {
  284. return getDeclaringClass().getName().hashCode();
  285. }
  286. /**
  287. * Returns a string describing this <code>Constructor</code>. The string is
  288. * formatted as the constructor access modifiers, if any,
  289. * followed by the fully-qualified name of the declaring class,
  290. * followed by a parenthesized, comma-separated list of the
  291. * constructor's formal parameter types. For example:
  292. * <pre>
  293. * public java.util.Hashtable(int,float)
  294. * </pre>
  295. *
  296. * <p>The only possible modifiers for constructors are the access
  297. * modifiers <tt>public</tt>, <tt>protected</tt> or
  298. * <tt>private</tt>. Only one of these may appear, or none if the
  299. * constructor has default (package) access.
  300. */
  301. public String toString() {
  302. try {
  303. StringBuffer sb = new StringBuffer();
  304. int mod = getModifiers();
  305. if (mod != 0) {
  306. sb.append(Modifier.toString(mod) + " ");
  307. }
  308. sb.append(Field.getTypeName(getDeclaringClass()));
  309. sb.append("(");
  310. Class[] params = parameterTypes; // avoid clone
  311. for (int j = 0; j < params.length; j++) {
  312. sb.append(Field.getTypeName(params[j]));
  313. if (j < (params.length - 1))
  314. sb.append(",");
  315. }
  316. sb.append(")");
  317. Class[] exceptions = exceptionTypes; // avoid clone
  318. if (exceptions.length > 0) {
  319. sb.append(" throws ");
  320. for (int k = 0; k < exceptions.length; k++) {
  321. sb.append(exceptions[k].getName());
  322. if (k < (exceptions.length - 1))
  323. sb.append(",");
  324. }
  325. }
  326. return sb.toString();
  327. } catch (Exception e) {
  328. return "<" + e + ">";
  329. }
  330. }
  331. /**
  332. * Returns a string describing this <code>Constructor</code>,
  333. * including type parameters. The string is formatted as the
  334. * constructor access modifiers, if any, followed by an
  335. * angle-bracketed comma separated list of the constructor's type
  336. * parameters, if any, followed by the fully-qualified name of the
  337. * declaring class, followed by a parenthesized, comma-separated
  338. * list of the constructor's generic formal parameter types. A
  339. * space is used to separate access modifiers from one another and
  340. * from the type parameters or return type. If there are no type
  341. * parameters, the type parameter list is elided; if the type
  342. * parameter list is present, a space separates the list from the
  343. * class name. If the constructor is declared to throw
  344. * exceptions, the parameter list is followed by a space, followed
  345. * by the word "<tt>throws</tt>" followed by a
  346. * comma-separated list of the thrown exception types.
  347. *
  348. * <p>The only possible modifiers for constructors are the access
  349. * modifiers <tt>public</tt>, <tt>protected</tt> or
  350. * <tt>private</tt>. Only one of these may appear, or none if the
  351. * constructor has default (package) access.
  352. *
  353. * @return a string describing this <code>Constructor</code>,
  354. * include type parameters
  355. *
  356. * @since 1.5
  357. */
  358. public String toGenericString() {
  359. try {
  360. StringBuilder sb = new StringBuilder();
  361. int mod = getModifiers();
  362. if (mod != 0) {
  363. sb.append(Modifier.toString(mod) + " ");
  364. }
  365. Type[] typeparms = getTypeParameters();
  366. if (typeparms.length > 0) {
  367. boolean first = true;
  368. sb.append("<");
  369. for(Type typeparm: typeparms) {
  370. if (!first)
  371. sb.append(",");
  372. if (typeparm instanceof Class)
  373. sb.append(((Class)typeparm).getName());
  374. else
  375. sb.append(typeparm.toString());
  376. first = false;
  377. }
  378. sb.append("> ");
  379. }
  380. sb.append(Field.getTypeName(getDeclaringClass()));
  381. sb.append("(");
  382. Type[] params = getGenericParameterTypes();
  383. for (int j = 0; j < params.length; j++) {
  384. sb.append((params[j] instanceof Class)?
  385. Field.getTypeName((Class)params[j]):
  386. (params[j].toString()) );
  387. if (j < (params.length - 1))
  388. sb.append(",");
  389. }
  390. sb.append(")");
  391. Type[] exceptions = getGenericExceptionTypes();
  392. if (exceptions.length > 0) {
  393. sb.append(" throws ");
  394. for (int k = 0; k < exceptions.length; k++) {
  395. sb.append((exceptions[k] instanceof Class)?
  396. ((Class)exceptions[k]).getName():
  397. exceptions[k].toString());
  398. if (k < (exceptions.length - 1))
  399. sb.append(",");
  400. }
  401. }
  402. return sb.toString();
  403. } catch (Exception e) {
  404. return "<" + e + ">";
  405. }
  406. }
  407. /**
  408. * Uses the constructor represented by this <code>Constructor</code> object to
  409. * create and initialize a new instance of the constructor's
  410. * declaring class, with the specified initialization parameters.
  411. * Individual parameters are automatically unwrapped to match
  412. * primitive formal parameters, and both primitive and reference
  413. * parameters are subject to method invocation conversions as necessary.
  414. *
  415. * <p>If the number of formal parameters required by the underlying constructor
  416. * is 0, the supplied <code>initargs</code> array may be of length 0 or null.
  417. *
  418. * <p>If the required access and argument checks succeed and the
  419. * instantiation will proceed, the constructor's declaring class
  420. * is initialized if it has not already been initialized.
  421. *
  422. * <p>If the constructor completes normally, returns the newly
  423. * created and initialized instance.
  424. *
  425. * @param initargs array of objects to be passed as arguments to
  426. * the constructor call; values of primitive types are wrapped in
  427. * a wrapper object of the appropriate type (e.g. a <tt>float</tt>
  428. * in a {@link java.lang.Float Float})
  429. *
  430. * @return a new object created by calling the constructor
  431. * this object represents
  432. *
  433. * @exception IllegalAccessException if this <code>Constructor</code> object
  434. * enforces Java language access control and the underlying
  435. * constructor is inaccessible.
  436. * @exception IllegalArgumentException if the number of actual
  437. * and formal parameters differ; if an unwrapping
  438. * conversion for primitive arguments fails; or if,
  439. * after possible unwrapping, a parameter value
  440. * cannot be converted to the corresponding formal
  441. * parameter type by a method invocation conversion; if
  442. * this constructor pertains to an enum type.
  443. * @exception InstantiationException if the class that declares the
  444. * underlying constructor represents an abstract class.
  445. * @exception InvocationTargetException if the underlying constructor
  446. * throws an exception.
  447. * @exception ExceptionInInitializerError if the initialization provoked
  448. * by this method fails.
  449. */
  450. public T newInstance(Object ... initargs)
  451. throws InstantiationException, IllegalAccessException,
  452. IllegalArgumentException, InvocationTargetException
  453. {
  454. if (!override) {
  455. if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
  456. Class caller = Reflection.getCallerClass(2);
  457. if (securityCheckCache != caller) {
  458. Reflection.ensureMemberAccess(caller, clazz, null, modifiers);
  459. securityCheckCache = caller;
  460. }
  461. }
  462. }
  463. if ((clazz.getModifiers() & Modifier.ENUM) != 0)
  464. throw new IllegalArgumentException("Cannot reflectively create enum objects");
  465. if (constructorAccessor == null) acquireConstructorAccessor();
  466. return (T) constructorAccessor.newInstance(initargs);
  467. }
  468. /**
  469. * Returns <tt>true</tt> if this constructor was declared to take
  470. * a variable number of arguments; returns <tt>false</tt>
  471. * otherwise.
  472. *
  473. * @return <tt>true</tt> if an only if this constructor was declared to
  474. * take a variable number of arguments.
  475. * @since 1.5
  476. */
  477. public boolean isVarArgs() {
  478. return (getModifiers() & Modifier.VARARGS) != 0;
  479. }
  480. /**
  481. * Returns <tt>true</tt> if this constructor is a synthetic
  482. * constructor; returns <tt>false</tt> otherwise.
  483. *
  484. * @return true if and only if this constructor is a synthetic
  485. * constructor as defined by the Java Language Specification.
  486. * @since 1.5
  487. */
  488. public boolean isSynthetic() {
  489. return Modifier.isSynthetic(getModifiers());
  490. }
  491. // NOTE that there is no synchronization used here. It is correct
  492. // (though not efficient) to generate more than one
  493. // ConstructorAccessor for a given Constructor. However, avoiding
  494. // synchronization will probably make the implementation more
  495. // scalable.
  496. private void acquireConstructorAccessor() {
  497. // First check to see if one has been created yet, and take it
  498. // if so.
  499. ConstructorAccessor tmp = null;
  500. if (root != null) tmp = root.getConstructorAccessor();
  501. if (tmp != null) {
  502. constructorAccessor = tmp;
  503. return;
  504. }
  505. // Otherwise fabricate one and propagate it up to the root
  506. tmp = reflectionFactory.newConstructorAccessor(this);
  507. setConstructorAccessor(tmp);
  508. }
  509. // Returns ConstructorAccessor for this Constructor object, not
  510. // looking up the chain to the root
  511. ConstructorAccessor getConstructorAccessor() {
  512. return constructorAccessor;
  513. }
  514. // Sets the ConstructorAccessor for this Constructor object and
  515. // (recursively) its root
  516. void setConstructorAccessor(ConstructorAccessor accessor) {
  517. constructorAccessor = accessor;
  518. // Propagate up
  519. if (root != null) {
  520. root.setConstructorAccessor(accessor);
  521. }
  522. }
  523. int getSlot() {
  524. return slot;
  525. }
  526. String getSignature() {
  527. return signature;
  528. }
  529. byte[] getRawAnnotations() {
  530. return annotations;
  531. }
  532. byte[] getRawParameterAnnotations() {
  533. return parameterAnnotations;
  534. }
  535. public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
  536. if (annotationClass == null)
  537. throw new NullPointerException();
  538. return (T) declaredAnnotations().get(annotationClass);
  539. }
  540. private static final Annotation[] EMPTY_ANNOTATION_ARRAY=new Annotation[0];
  541. public Annotation[] getDeclaredAnnotations() {
  542. return declaredAnnotations().values().toArray(EMPTY_ANNOTATION_ARRAY);
  543. }
  544. private transient Map<Class, Annotation> declaredAnnotations;
  545. private synchronized Map<Class, Annotation> declaredAnnotations() {
  546. if (declaredAnnotations == null) {
  547. declaredAnnotations = AnnotationParser.parseAnnotations(
  548. annotations, sun.misc.SharedSecrets.getJavaLangAccess().
  549. getConstantPool(getDeclaringClass()),
  550. getDeclaringClass());
  551. }
  552. return declaredAnnotations;
  553. }
  554. /**
  555. * Returns an array of arrays that represent the annotations on the formal
  556. * parameters, in declaration order, of the method represented by
  557. * this <tt>Method</tt> object. (Returns an array of length zero if the
  558. * underlying method is parameterless. If the method has one or more
  559. * parameters, a nested array of length zero is returned for each parameter
  560. * with no annotations.) The annotation objects contained in the returned
  561. * arrays are serializable. The caller of this method is free to modify
  562. * the returned arrays; it will have no effect on the arrays returned to
  563. * other callers.
  564. *
  565. * @return an array of arrays that represent the annotations on the formal
  566. * parameters, in declaration order, of the method represented by this
  567. * Method object
  568. * @since 1.5
  569. */
  570. public Annotation[][] getParameterAnnotations() {
  571. int numParameters = parameterTypes.length;
  572. if (parameterAnnotations == null)
  573. return new Annotation[numParameters][0];
  574. Annotation[][] result = AnnotationParser.parseParameterAnnotations(
  575. parameterAnnotations,
  576. sun.misc.SharedSecrets.getJavaLangAccess().
  577. getConstantPool(getDeclaringClass()),
  578. getDeclaringClass());
  579. if (result.length != numParameters)
  580. throw new java.lang.annotation.AnnotationFormatError(
  581. "Parameter annotations don't match number of parameters");
  582. return result;
  583. }
  584. }