1. /*
  2. * @(#)Field.java 1.42 04/05/11
  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.FieldAccessor;
  9. import sun.reflect.Reflection;
  10. import sun.reflect.generics.repository.FieldRepository;
  11. import sun.reflect.generics.factory.CoreReflectionFactory;
  12. import sun.reflect.generics.factory.GenericsFactory;
  13. import sun.reflect.generics.scope.ClassScope;
  14. import java.lang.annotation.Annotation;
  15. import java.util.Map;
  16. import sun.reflect.annotation.AnnotationParser;
  17. /**
  18. * A <code>Field</code> provides information about, and dynamic access to, a
  19. * single field of a class or an interface. The reflected field may
  20. * be a class (static) field or an instance field.
  21. *
  22. * <p>A <code>Field</code> permits widening conversions to occur during a get or
  23. * set access operation, but throws an <code>IllegalArgumentException</code> if a
  24. * narrowing conversion would occur.
  25. *
  26. * @see Member
  27. * @see java.lang.Class
  28. * @see java.lang.Class#getFields()
  29. * @see java.lang.Class#getField(String)
  30. * @see java.lang.Class#getDeclaredFields()
  31. * @see java.lang.Class#getDeclaredField(String)
  32. *
  33. * @author Kenneth Russell
  34. * @author Nakul Saraiya
  35. */
  36. public final
  37. class Field extends AccessibleObject implements Member {
  38. private Class clazz;
  39. private int slot;
  40. // This is guaranteed to be interned by the VM in the 1.4
  41. // reflection implementation
  42. private String name;
  43. private Class type;
  44. private int modifiers;
  45. // Generics and annotations support
  46. private transient String signature;
  47. // generic info repository; lazily initialized
  48. private transient FieldRepository genericInfo;
  49. private byte[] annotations;
  50. // Cached field accessor created without override
  51. private FieldAccessor fieldAccessor;
  52. // Cached field accessor created with override
  53. private FieldAccessor overrideFieldAccessor;
  54. // For sharing of FieldAccessors. This branching structure is
  55. // currently only two levels deep (i.e., one root Field and
  56. // potentially many Field objects pointing to it.)
  57. private Field root;
  58. // More complicated security check cache needed here than for
  59. // Class.newInstance() and Constructor.newInstance()
  60. private volatile Class securityCheckTargetClassCache;
  61. // Generics infrastructure
  62. private String getGenericSignature() {return signature;}
  63. // Accessor for factory
  64. private GenericsFactory getFactory() {
  65. Class<?> c = getDeclaringClass();
  66. // create scope and factory
  67. return CoreReflectionFactory.make(c, ClassScope.make(c));
  68. }
  69. // Accessor for generic info repository
  70. private FieldRepository getGenericInfo() {
  71. // lazily initialize repository if necessary
  72. if (genericInfo == null) {
  73. // create and cache generic info repository
  74. genericInfo = FieldRepository.make(getGenericSignature(),
  75. getFactory());
  76. }
  77. return genericInfo; //return cached repository
  78. }
  79. /**
  80. * Package-private constructor used by ReflectAccess to enable
  81. * instantiation of these objects in Java code from the java.lang
  82. * package via sun.reflect.LangReflectAccess.
  83. */
  84. Field(Class declaringClass,
  85. String name,
  86. Class type,
  87. int modifiers,
  88. int slot,
  89. String signature,
  90. byte[] annotations)
  91. {
  92. this.clazz = declaringClass;
  93. this.name = name;
  94. this.type = type;
  95. this.modifiers = modifiers;
  96. this.slot = slot;
  97. this.signature = signature;
  98. this.annotations = annotations;
  99. }
  100. /**
  101. * Package-private routine (exposed to java.lang.Class via
  102. * ReflectAccess) which returns a copy of this Field. The copy's
  103. * "root" field points to this Field.
  104. */
  105. Field copy() {
  106. // This routine enables sharing of FieldAccessor objects
  107. // among Field objects which refer to the same underlying
  108. // method in the VM. (All of this contortion is only necessary
  109. // because of the "accessibility" bit in AccessibleObject,
  110. // which implicitly requires that new java.lang.reflect
  111. // objects be fabricated for each reflective call on Class
  112. // objects.)
  113. Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations);
  114. res.root = this;
  115. // Might as well eagerly propagate this if already present
  116. res.fieldAccessor = fieldAccessor;
  117. res.overrideFieldAccessor = overrideFieldAccessor;
  118. return res;
  119. }
  120. /**
  121. * Returns the <code>Class</code> object representing the class or interface
  122. * that declares the field represented by this <code>Field</code> object.
  123. */
  124. public Class<?> getDeclaringClass() {
  125. return clazz;
  126. }
  127. /**
  128. * Returns the name of the field represented by this <code>Field</code> object.
  129. */
  130. public String getName() {
  131. return name;
  132. }
  133. /**
  134. * Returns the Java language modifiers for the field represented
  135. * by this <code>Field</code> object, as an integer. The <code>Modifier</code> class should
  136. * be used to decode the modifiers.
  137. *
  138. * @see Modifier
  139. */
  140. public int getModifiers() {
  141. return modifiers;
  142. }
  143. /**
  144. * Returns <tt>true</tt> if this field represents an element of
  145. * an enumerated type; returns <tt>false</tt> otherwise.
  146. *
  147. * @return <tt>true</tt> if and only if this field represents an element of
  148. * an enumerated type.
  149. * @since 1.5
  150. */
  151. public boolean isEnumConstant() {
  152. return (getModifiers() & Modifier.ENUM) != 0;
  153. }
  154. /**
  155. * Returns <tt>true</tt> if this field is a synthetic
  156. * field; returns <tt>false</tt> otherwise.
  157. *
  158. * @return true if and only if this field is a synthetic
  159. * field as defined by the Java Language Specification.
  160. * @since 1.5
  161. */
  162. public boolean isSynthetic() {
  163. return Modifier.isSynthetic(getModifiers());
  164. }
  165. /**
  166. * Returns a <code>Class</code> object that identifies the
  167. * declared type for the field represented by this
  168. * <code>Field</code> object.
  169. *
  170. * @return a <code>Class</code> object identifying the declared
  171. * type of the field represented by this object
  172. */
  173. public Class<?> getType() {
  174. return type;
  175. }
  176. /**
  177. * Returns a <tt>Type</tt> object that represents the declared type for
  178. * the field represented by this <tt>Field</tt> object.
  179. *
  180. * <p>If the <tt>Type</tt> is a parameterized type, the
  181. * <tt>Type</tt> object returned must accurately reflect the
  182. * actual type parameters used in the source code.
  183. *
  184. * <p>If an the type of the underlying field is a type variable or a
  185. * parameterized type, it is created. Otherwise, it is resolved.
  186. *
  187. * @return a <tt>Type</tt> object that represents the declared type for
  188. * the field represented by this <tt>Field</tt> object
  189. * @throws GenericSignatureFormatError if the generic field
  190. * signature does not conform to the format specified in the Java
  191. * Virtual Machine Specification, 3rd edition
  192. * @throws TypeNotPresentException if the generic type
  193. * signature of the underlying field refers to a non-existent
  194. * type declaration
  195. * @throws MalformedParameterizedTypeException if the generic
  196. * signature of the underlying field refers to a parameterized type
  197. * that cannot be instantiated for any reason
  198. * @since 1.5
  199. */
  200. public Type getGenericType() {
  201. if (getGenericSignature() != null)
  202. return getGenericInfo().getGenericType();
  203. else
  204. return getType();
  205. }
  206. /**
  207. * Compares this <code>Field</code> against the specified object. Returns
  208. * true if the objects are the same. Two <code>Field</code> objects are the same if
  209. * they were declared by the same class and have the same name
  210. * and type.
  211. */
  212. public boolean equals(Object obj) {
  213. if (obj != null && obj instanceof Field) {
  214. Field other = (Field)obj;
  215. return (getDeclaringClass() == other.getDeclaringClass())
  216. && (getName() == other.getName())
  217. && (getType() == other.getType());
  218. }
  219. return false;
  220. }
  221. /**
  222. * Returns a hashcode for this <code>Field</code>. This is computed as the
  223. * exclusive-or of the hashcodes for the underlying field's
  224. * declaring class name and its name.
  225. */
  226. public int hashCode() {
  227. return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
  228. }
  229. /**
  230. * Returns a string describing this <code>Field</code>. The format is
  231. * the access modifiers for the field, if any, followed
  232. * by the field type, followed by a space, followed by
  233. * the fully-qualified name of the class declaring the field,
  234. * followed by a period, followed by the name of the field.
  235. * For example:
  236. * <pre>
  237. * public static final int java.lang.Thread.MIN_PRIORITY
  238. * private int java.io.FileDescriptor.fd
  239. * </pre>
  240. *
  241. * <p>The modifiers are placed in canonical order as specified by
  242. * "The Java Language Specification". This is <tt>public</tt>,
  243. * <tt>protected</tt> or <tt>private</tt> first, and then other
  244. * modifiers in the following order: <tt>static</tt>, <tt>final</tt>,
  245. * <tt>transient</tt>, <tt>volatile</tt>.
  246. */
  247. public String toString() {
  248. int mod = getModifiers();
  249. return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
  250. + getTypeName(getType()) + " "
  251. + getTypeName(getDeclaringClass()) + "."
  252. + getName());
  253. }
  254. /**
  255. * Returns a string describing this <code>Field</code>, including
  256. * its generic type. The format is the access modifiers for the
  257. * field, if any, followed by the generic field type, followed by
  258. * a space, followed by the fully-qualified name of the class
  259. * declaring the field, followed by a period, followed by the name
  260. * of the field.
  261. *
  262. * <p>The modifiers are placed in canonical order as specified by
  263. * "The Java Language Specification". This is <tt>public</tt>,
  264. * <tt>protected</tt> or <tt>private</tt> first, and then other
  265. * modifiers in the following order: <tt>static</tt>, <tt>final</tt>,
  266. * <tt>transient</tt>, <tt>volatile</tt>.
  267. *
  268. * @return a string describing this <code>Field</code>, including
  269. * its generic type
  270. *
  271. * @since 1.5
  272. */
  273. public String toGenericString() {
  274. int mod = getModifiers();
  275. Type fieldType = getGenericType();
  276. return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
  277. + ((fieldType instanceof Class) ?
  278. getTypeName((Class)fieldType): fieldType.toString())+ " "
  279. + getTypeName(getDeclaringClass()) + "."
  280. + getName());
  281. }
  282. /**
  283. * Returns the value of the field represented by this <code>Field</code>, on
  284. * the specified object. The value is automatically wrapped in an
  285. * object if it has a primitive type.
  286. *
  287. * <p>The underlying field's value is obtained as follows:
  288. *
  289. * <p>If the underlying field is a static field, the <code>obj</code> argument
  290. * is ignored; it may be null.
  291. *
  292. * <p>Otherwise, the underlying field is an instance field. If the
  293. * specified <code>obj</code> argument is null, the method throws a
  294. * <code>NullPointerException.</code> If the specified object is not an
  295. * instance of the class or interface declaring the underlying
  296. * field, the method throws an <code>IllegalArgumentException</code>.
  297. *
  298. * <p>If this <code>Field</code> object enforces Java language access control, and
  299. * the underlying field is inaccessible, the method throws an
  300. * <code>IllegalAccessException</code>.
  301. * If the underlying field is static, the class that declared the
  302. * field is initialized if it has not already been initialized.
  303. *
  304. * <p>Otherwise, the value is retrieved from the underlying instance
  305. * or static field. If the field has a primitive type, the value
  306. * is wrapped in an object before being returned, otherwise it is
  307. * returned as is.
  308. *
  309. * <p>If the field is hidden in the type of <code>obj</code>,
  310. * the field's value is obtained according to the preceding rules.
  311. *
  312. * @param obj object from which the represented field's value is
  313. * to be extracted
  314. * @return the value of the represented field in object
  315. * <tt>obj</tt> primitive values are wrapped in an appropriate
  316. * object before being returned
  317. *
  318. * @exception IllegalAccessException if the underlying field
  319. * is inaccessible.
  320. * @exception IllegalArgumentException if the specified object is not an
  321. * instance of the class or interface declaring the underlying
  322. * field (or a subclass or implementor thereof).
  323. * @exception NullPointerException if the specified object is null
  324. * and the field is an instance field.
  325. * @exception ExceptionInInitializerError if the initialization provoked
  326. * by this method fails.
  327. */
  328. public Object get(Object obj)
  329. throws IllegalArgumentException, IllegalAccessException
  330. {
  331. return getFieldAccessor(obj).get(obj);
  332. }
  333. /**
  334. * Gets the value of a static or instance <code>boolean</code> field.
  335. *
  336. * @param obj the object to extract the <code>boolean</code> value
  337. * from
  338. * @return the value of the <code>boolean</code> field
  339. *
  340. * @exception IllegalAccessException if the underlying field
  341. * is inaccessible.
  342. * @exception IllegalArgumentException if the specified object is not
  343. * an instance of the class or interface declaring the
  344. * underlying field (or a subclass or implementor
  345. * thereof), or if the field value cannot be
  346. * converted to the type <code>boolean</code> by a
  347. * widening conversion.
  348. * @exception NullPointerException if the specified object is null
  349. * and the field is an instance field.
  350. * @exception ExceptionInInitializerError if the initialization provoked
  351. * by this method fails.
  352. * @see Field#get
  353. */
  354. public boolean getBoolean(Object obj)
  355. throws IllegalArgumentException, IllegalAccessException
  356. {
  357. return getFieldAccessor(obj).getBoolean(obj);
  358. }
  359. /**
  360. * Gets the value of a static or instance <code>byte</code> field.
  361. *
  362. * @param obj the object to extract the <code>byte</code> value
  363. * from
  364. * @return the value of the <code>byte</code> field
  365. *
  366. * @exception IllegalAccessException if the underlying field
  367. * is inaccessible.
  368. * @exception IllegalArgumentException if the specified object is not
  369. * an instance of the class or interface declaring the
  370. * underlying field (or a subclass or implementor
  371. * thereof), or if the field value cannot be
  372. * converted to the type <code>byte</code> by a
  373. * widening conversion.
  374. * @exception NullPointerException if the specified object is null
  375. * and the field is an instance field.
  376. * @exception ExceptionInInitializerError if the initialization provoked
  377. * by this method fails.
  378. * @see Field#get
  379. */
  380. public byte getByte(Object obj)
  381. throws IllegalArgumentException, IllegalAccessException
  382. {
  383. return getFieldAccessor(obj).getByte(obj);
  384. }
  385. /**
  386. * Gets the value of a static or instance field of type
  387. * <code>char</code> or of another primitive type convertible to
  388. * type <code>char</code> via a widening conversion.
  389. *
  390. * @param obj the object to extract the <code>char</code> value
  391. * from
  392. * @return the value of the field converted to type <code>char</code>
  393. *
  394. * @exception IllegalAccessException if the underlying field
  395. * is inaccessible.
  396. * @exception IllegalArgumentException if the specified object is not
  397. * an instance of the class or interface declaring the
  398. * underlying field (or a subclass or implementor
  399. * thereof), or if the field value cannot be
  400. * converted to the type <code>char</code> by a
  401. * widening conversion.
  402. * @exception NullPointerException if the specified object is null
  403. * and the field is an instance field.
  404. * @exception ExceptionInInitializerError if the initialization provoked
  405. * by this method fails.
  406. * @see Field#get
  407. */
  408. public char getChar(Object obj)
  409. throws IllegalArgumentException, IllegalAccessException
  410. {
  411. return getFieldAccessor(obj).getChar(obj);
  412. }
  413. /**
  414. * Gets the value of a static or instance field of type
  415. * <code>short</code> or of another primitive type convertible to
  416. * type <code>short</code> via a widening conversion.
  417. *
  418. * @param obj the object to extract the <code>short</code> value
  419. * from
  420. * @return the value of the field converted to type <code>short</code>
  421. *
  422. * @exception IllegalAccessException if the underlying field
  423. * is inaccessible.
  424. * @exception IllegalArgumentException if the specified object is not
  425. * an instance of the class or interface declaring the
  426. * underlying field (or a subclass or implementor
  427. * thereof), or if the field value cannot be
  428. * converted to the type <code>short</code> by a
  429. * widening conversion.
  430. * @exception NullPointerException if the specified object is null
  431. * and the field is an instance field.
  432. * @exception ExceptionInInitializerError if the initialization provoked
  433. * by this method fails.
  434. * @see Field#get
  435. */
  436. public short getShort(Object obj)
  437. throws IllegalArgumentException, IllegalAccessException
  438. {
  439. return getFieldAccessor(obj).getShort(obj);
  440. }
  441. /**
  442. * Gets the value of a static or instance field of type
  443. * <code>int</code> or of another primitive type convertible to
  444. * type <code>int</code> via a widening conversion.
  445. *
  446. * @param obj the object to extract the <code>int</code> value
  447. * from
  448. * @return the value of the field converted to type <code>int</code>
  449. *
  450. * @exception IllegalAccessException if the underlying field
  451. * is inaccessible.
  452. * @exception IllegalArgumentException if the specified object is not
  453. * an instance of the class or interface declaring the
  454. * underlying field (or a subclass or implementor
  455. * thereof), or if the field value cannot be
  456. * converted to the type <code>int</code> by a
  457. * widening conversion.
  458. * @exception NullPointerException if the specified object is null
  459. * and the field is an instance field.
  460. * @exception ExceptionInInitializerError if the initialization provoked
  461. * by this method fails.
  462. * @see Field#get
  463. */
  464. public int getInt(Object obj)
  465. throws IllegalArgumentException, IllegalAccessException
  466. {
  467. return getFieldAccessor(obj).getInt(obj);
  468. }
  469. /**
  470. * Gets the value of a static or instance field of type
  471. * <code>long</code> or of another primitive type convertible to
  472. * type <code>long</code> via a widening conversion.
  473. *
  474. * @param obj the object to extract the <code>long</code> value
  475. * from
  476. * @return the value of the field converted to type <code>long</code>
  477. *
  478. * @exception IllegalAccessException if the underlying field
  479. * is inaccessible.
  480. * @exception IllegalArgumentException if the specified object is not
  481. * an instance of the class or interface declaring the
  482. * underlying field (or a subclass or implementor
  483. * thereof), or if the field value cannot be
  484. * converted to the type <code>long</code> by a
  485. * widening conversion.
  486. * @exception NullPointerException if the specified object is null
  487. * and the field is an instance field.
  488. * @exception ExceptionInInitializerError if the initialization provoked
  489. * by this method fails.
  490. * @see Field#get
  491. */
  492. public long getLong(Object obj)
  493. throws IllegalArgumentException, IllegalAccessException
  494. {
  495. return getFieldAccessor(obj).getLong(obj);
  496. }
  497. /**
  498. * Gets the value of a static or instance field of type
  499. * <code>float</code> or of another primitive type convertible to
  500. * type <code>float</code> via a widening conversion.
  501. *
  502. * @param obj the object to extract the <code>float</code> value
  503. * from
  504. * @return the value of the field converted to type <code>float</code>
  505. *
  506. * @exception IllegalAccessException if the underlying field
  507. * is inaccessible.
  508. * @exception IllegalArgumentException if the specified object is not
  509. * an instance of the class or interface declaring the
  510. * underlying field (or a subclass or implementor
  511. * thereof), or if the field value cannot be
  512. * converted to the type <code>float</code> by a
  513. * widening conversion.
  514. * @exception NullPointerException if the specified object is null
  515. * and the field is an instance field.
  516. * @exception ExceptionInInitializerError if the initialization provoked
  517. * by this method fails.
  518. * @see Field#get
  519. */
  520. public float getFloat(Object obj)
  521. throws IllegalArgumentException, IllegalAccessException
  522. {
  523. return getFieldAccessor(obj).getFloat(obj);
  524. }
  525. /**
  526. * Gets the value of a static or instance field of type
  527. * <code>double</code> or of another primitive type convertible to
  528. * type <code>double</code> via a widening conversion.
  529. *
  530. * @param obj the object to extract the <code>double</code> value
  531. * from
  532. * @return the value of the field converted to type <code>double</code>
  533. *
  534. * @exception IllegalAccessException if the underlying field
  535. * is inaccessible.
  536. * @exception IllegalArgumentException if the specified object is not
  537. * an instance of the class or interface declaring the
  538. * underlying field (or a subclass or implementor
  539. * thereof), or if the field value cannot be
  540. * converted to the type <code>double</code> by a
  541. * widening conversion.
  542. * @exception NullPointerException if the specified object is null
  543. * and the field is an instance field.
  544. * @exception ExceptionInInitializerError if the initialization provoked
  545. * by this method fails.
  546. * @see Field#get
  547. */
  548. public double getDouble(Object obj)
  549. throws IllegalArgumentException, IllegalAccessException
  550. {
  551. return getFieldAccessor(obj).getDouble(obj);
  552. }
  553. /**
  554. * Sets the field represented by this <code>Field</code> object on the
  555. * specified object argument to the specified new value. The new
  556. * value is automatically unwrapped if the underlying field has a
  557. * primitive type.
  558. *
  559. * <p>The operation proceeds as follows:
  560. *
  561. * <p>If the underlying field is static, the <code>obj</code> argument is
  562. * ignored; it may be null.
  563. *
  564. * <p>Otherwise the underlying field is an instance field. If the
  565. * specified object argument is null, the method throws a
  566. * <code>NullPointerException</code>. If the specified object argument is not
  567. * an instance of the class or interface declaring the underlying
  568. * field, the method throws an <code>IllegalArgumentException</code>.
  569. *
  570. * <p>If this <code>Field</code> object enforces Java language access control, and
  571. * the underlying field is inaccessible, the method throws an
  572. * <code>IllegalAccessException</code>.
  573. *
  574. * <p>If the underlying field is final, the method throws an
  575. * <code>IllegalAccessException</code> unless
  576. * <code>setAccessible(true)</code> has succeeded for this field
  577. * and this field is non-static. Setting a final field in this way
  578. * is meaningful only during deserialization or reconstruction of
  579. * instances of classes with blank final fields, before they are
  580. * made available for access by other parts of a program. Use in
  581. * any other context may have unpredictable effects, including cases
  582. * in which other parts of a program continue to use the original
  583. * value of this field.
  584. *
  585. * <p>If the underlying field is of a primitive type, an unwrapping
  586. * conversion is attempted to convert the new value to a value of
  587. * a primitive type. If this attempt fails, the method throws an
  588. * <code>IllegalArgumentException</code>.
  589. *
  590. * <p>If, after possible unwrapping, the new value cannot be
  591. * converted to the type of the underlying field by an identity or
  592. * widening conversion, the method throws an
  593. * <code>IllegalArgumentException</code>.
  594. *
  595. * <p>If the underlying field is static, the class that declared the
  596. * field is initialized if it has not already been initialized.
  597. *
  598. * <p>The field is set to the possibly unwrapped and widened new value.
  599. *
  600. * <p>If the field is hidden in the type of <code>obj</code>,
  601. * the field's value is set according to the preceding rules.
  602. *
  603. * @param obj the object whose field should be modified
  604. * @param value the new value for the field of <code>obj</code>
  605. * being modified
  606. *
  607. * @exception IllegalAccessException if the underlying field
  608. * is inaccessible.
  609. * @exception IllegalArgumentException if the specified object is not an
  610. * instance of the class or interface declaring the underlying
  611. * field (or a subclass or implementor thereof),
  612. * or if an unwrapping conversion fails.
  613. * @exception NullPointerException if the specified object is null
  614. * and the field is an instance field.
  615. * @exception ExceptionInInitializerError if the initialization provoked
  616. * by this method fails.
  617. */
  618. public void set(Object obj, Object value)
  619. throws IllegalArgumentException, IllegalAccessException
  620. {
  621. getFieldAccessor(obj).set(obj, value);
  622. }
  623. /**
  624. * Sets the value of a field as a <code>boolean</code> on the specified object.
  625. * This method is equivalent to
  626. * <code>set(obj, zObj)</code>,
  627. * where <code>zObj</code> is a <code>Boolean</code> object and
  628. * <code>zObj.booleanValue() == z</code>.
  629. *
  630. * @param obj the object whose field should be modified
  631. * @param z the new value for the field of <code>obj</code>
  632. * being modified
  633. *
  634. * @exception IllegalAccessException if the underlying field
  635. * is inaccessible.
  636. * @exception IllegalArgumentException if the specified object is not an
  637. * instance of the class or interface declaring the underlying
  638. * field (or a subclass or implementor thereof),
  639. * or if an unwrapping conversion fails.
  640. * @exception NullPointerException if the specified object is null
  641. * and the field is an instance field.
  642. * @exception ExceptionInInitializerError if the initialization provoked
  643. * by this method fails.
  644. * @see Field#set
  645. */
  646. public void setBoolean(Object obj, boolean z)
  647. throws IllegalArgumentException, IllegalAccessException
  648. {
  649. getFieldAccessor(obj).setBoolean(obj, z);
  650. }
  651. /**
  652. * Sets the value of a field as a <code>byte</code> on the specified object.
  653. * This method is equivalent to
  654. * <code>set(obj, bObj)</code>,
  655. * where <code>bObj</code> is a <code>Byte</code> object and
  656. * <code>bObj.byteValue() == b</code>.
  657. *
  658. * @param obj the object whose field should be modified
  659. * @param b the new value for the field of <code>obj</code>
  660. * being modified
  661. *
  662. * @exception IllegalAccessException if the underlying field
  663. * is inaccessible.
  664. * @exception IllegalArgumentException if the specified object is not an
  665. * instance of the class or interface declaring the underlying
  666. * field (or a subclass or implementor thereof),
  667. * or if an unwrapping conversion fails.
  668. * @exception NullPointerException if the specified object is null
  669. * and the field is an instance field.
  670. * @exception ExceptionInInitializerError if the initialization provoked
  671. * by this method fails.
  672. * @see Field#set
  673. */
  674. public void setByte(Object obj, byte b)
  675. throws IllegalArgumentException, IllegalAccessException
  676. {
  677. getFieldAccessor(obj).setByte(obj, b);
  678. }
  679. /**
  680. * Sets the value of a field as a <code>char</code> on the specified object.
  681. * This method is equivalent to
  682. * <code>set(obj, cObj)</code>,
  683. * where <code>cObj</code> is a <code>Character</code> object and
  684. * <code>cObj.charValue() == c</code>.
  685. *
  686. * @param obj the object whose field should be modified
  687. * @param c the new value for the field of <code>obj</code>
  688. * being modified
  689. *
  690. * @exception IllegalAccessException if the underlying field
  691. * is inaccessible.
  692. * @exception IllegalArgumentException if the specified object is not an
  693. * instance of the class or interface declaring the underlying
  694. * field (or a subclass or implementor thereof),
  695. * or if an unwrapping conversion fails.
  696. * @exception NullPointerException if the specified object is null
  697. * and the field is an instance field.
  698. * @exception ExceptionInInitializerError if the initialization provoked
  699. * by this method fails.
  700. * @see Field#set
  701. */
  702. public void setChar(Object obj, char c)
  703. throws IllegalArgumentException, IllegalAccessException
  704. {
  705. getFieldAccessor(obj).setChar(obj, c);
  706. }
  707. /**
  708. * Sets the value of a field as a <code>short</code> on the specified object.
  709. * This method is equivalent to
  710. * <code>set(obj, sObj)</code>,
  711. * where <code>sObj</code> is a <code>Short</code> object and
  712. * <code>sObj.shortValue() == s</code>.
  713. *
  714. * @param obj the object whose field should be modified
  715. * @param s the new value for the field of <code>obj</code>
  716. * being modified
  717. *
  718. * @exception IllegalAccessException if the underlying field
  719. * is inaccessible.
  720. * @exception IllegalArgumentException if the specified object is not an
  721. * instance of the class or interface declaring the underlying
  722. * field (or a subclass or implementor thereof),
  723. * or if an unwrapping conversion fails.
  724. * @exception NullPointerException if the specified object is null
  725. * and the field is an instance field.
  726. * @exception ExceptionInInitializerError if the initialization provoked
  727. * by this method fails.
  728. * @see Field#set
  729. */
  730. public void setShort(Object obj, short s)
  731. throws IllegalArgumentException, IllegalAccessException
  732. {
  733. getFieldAccessor(obj).setShort(obj, s);
  734. }
  735. /**
  736. * Sets the value of a field as an <code>int</code> on the specified object.
  737. * This method is equivalent to
  738. * <code>set(obj, iObj)</code>,
  739. * where <code>iObj</code> is a <code>Integer</code> object and
  740. * <code>iObj.intValue() == i</code>.
  741. *
  742. * @param obj the object whose field should be modified
  743. * @param i the new value for the field of <code>obj</code>
  744. * being modified
  745. *
  746. * @exception IllegalAccessException if the underlying field
  747. * is inaccessible.
  748. * @exception IllegalArgumentException if the specified object is not an
  749. * instance of the class or interface declaring the underlying
  750. * field (or a subclass or implementor thereof),
  751. * or if an unwrapping conversion fails.
  752. * @exception NullPointerException if the specified object is null
  753. * and the field is an instance field.
  754. * @exception ExceptionInInitializerError if the initialization provoked
  755. * by this method fails.
  756. * @see Field#set
  757. */
  758. public void setInt(Object obj, int i)
  759. throws IllegalArgumentException, IllegalAccessException
  760. {
  761. getFieldAccessor(obj).setInt(obj, i);
  762. }
  763. /**
  764. * Sets the value of a field as a <code>long</code> on the specified object.
  765. * This method is equivalent to
  766. * <code>set(obj, lObj)</code>,
  767. * where <code>lObj</code> is a <code>Long</code> object and
  768. * <code>lObj.longValue() == l</code>.
  769. *
  770. * @param obj the object whose field should be modified
  771. * @param l the new value for the field of <code>obj</code>
  772. * being modified
  773. *
  774. * @exception IllegalAccessException if the underlying field
  775. * is inaccessible.
  776. * @exception IllegalArgumentException if the specified object is not an
  777. * instance of the class or interface declaring the underlying
  778. * field (or a subclass or implementor thereof),
  779. * or if an unwrapping conversion fails.
  780. * @exception NullPointerException if the specified object is null
  781. * and the field is an instance field.
  782. * @exception ExceptionInInitializerError if the initialization provoked
  783. * by this method fails.
  784. * @see Field#set
  785. */
  786. public void setLong(Object obj, long l)
  787. throws IllegalArgumentException, IllegalAccessException
  788. {
  789. getFieldAccessor(obj).setLong(obj, l);
  790. }
  791. /**
  792. * Sets the value of a field as a <code>float</code> on the specified object.
  793. * This method is equivalent to
  794. * <code>set(obj, fObj)</code>,
  795. * where <code>fObj</code> is a <code>Float</code> object and
  796. * <code>fObj.floatValue() == f</code>.
  797. *
  798. * @param obj the object whose field should be modified
  799. * @param f the new value for the field of <code>obj</code>
  800. * being modified
  801. *
  802. * @exception IllegalAccessException if the underlying field
  803. * is inaccessible.
  804. * @exception IllegalArgumentException if the specified object is not an
  805. * instance of the class or interface declaring the underlying
  806. * field (or a subclass or implementor thereof),
  807. * or if an unwrapping conversion fails.
  808. * @exception NullPointerException if the specified object is null
  809. * and the field is an instance field.
  810. * @exception ExceptionInInitializerError if the initialization provoked
  811. * by this method fails.
  812. * @see Field#set
  813. */
  814. public void setFloat(Object obj, float f)
  815. throws IllegalArgumentException, IllegalAccessException
  816. {
  817. getFieldAccessor(obj).setFloat(obj, f);
  818. }
  819. /**
  820. * Sets the value of a field as a <code>double</code> on the specified object.
  821. * This method is equivalent to
  822. * <code>set(obj, dObj)</code>,
  823. * where <code>dObj</code> is a <code>Double</code> object and
  824. * <code>dObj.doubleValue() == d</code>.
  825. *
  826. * @param obj the object whose field should be modified
  827. * @param d the new value for the field of <code>obj</code>
  828. * being modified
  829. *
  830. * @exception IllegalAccessException if the underlying field
  831. * is inaccessible.
  832. * @exception IllegalArgumentException if the specified object is not an
  833. * instance of the class or interface declaring the underlying
  834. * field (or a subclass or implementor thereof),
  835. * or if an unwrapping conversion fails.
  836. * @exception NullPointerException if the specified object is null
  837. * and the field is an instance field.
  838. * @exception ExceptionInInitializerError if the initialization provoked
  839. * by this method fails.
  840. * @see Field#set
  841. */
  842. public void setDouble(Object obj, double d)
  843. throws IllegalArgumentException, IllegalAccessException
  844. {
  845. getFieldAccessor(obj).setDouble(obj, d);
  846. }
  847. // Convenience routine which performs security checks
  848. private FieldAccessor getFieldAccessor(Object obj)
  849. throws IllegalAccessException
  850. {
  851. doSecurityCheck(obj);
  852. boolean ov = override;
  853. FieldAccessor a = (ov)? overrideFieldAccessor : fieldAccessor;
  854. return (a != null)? a : acquireFieldAccessor(ov);
  855. }
  856. // NOTE that there is no synchronization used here. It is correct
  857. // (though not efficient) to generate more than one FieldAccessor
  858. // for a given Field. However, avoiding synchronization will
  859. // probably make the implementation more scalable.
  860. private FieldAccessor acquireFieldAccessor(boolean overrideFinalCheck) {
  861. // First check to see if one has been created yet, and take it
  862. // if so
  863. FieldAccessor tmp = null;
  864. if (root != null) tmp = root.getFieldAccessor(overrideFinalCheck);
  865. if (tmp != null) {
  866. if (overrideFinalCheck)
  867. overrideFieldAccessor = tmp;
  868. else
  869. fieldAccessor = tmp;
  870. } else {
  871. // Otherwise fabricate one and propagate it up to the root
  872. tmp = reflectionFactory.newFieldAccessor(this, overrideFinalCheck);
  873. setFieldAccessor(tmp, overrideFinalCheck);
  874. }
  875. return tmp;
  876. }
  877. // Returns FieldAccessor for this Field object, not looking up
  878. // the chain to the root
  879. private FieldAccessor getFieldAccessor(boolean overrideFinalCheck) {
  880. return (overrideFinalCheck)? overrideFieldAccessor : fieldAccessor;
  881. }
  882. // Sets the FieldAccessor for this Field object and
  883. // (recursively) its root
  884. private void setFieldAccessor(FieldAccessor accessor, boolean overrideFinalCheck) {
  885. if (overrideFinalCheck)
  886. overrideFieldAccessor = accessor;
  887. else
  888. fieldAccessor = accessor;
  889. // Propagate up
  890. if (root != null) {
  891. root.setFieldAccessor(accessor, overrideFinalCheck);
  892. }
  893. }
  894. // NOTE: be very careful if you change the stack depth of this
  895. // routine. The depth of the "getCallerClass" call is hardwired so
  896. // that the compiler can have an easier time if this gets inlined.
  897. private void doSecurityCheck(Object obj) throws IllegalAccessException {
  898. if (!override) {
  899. if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
  900. Class caller = Reflection.getCallerClass(4);
  901. Class targetClass = ((obj == null || !Modifier.isProtected(modifiers))
  902. ? clazz
  903. : obj.getClass());
  904. if (securityCheckCache != caller ||
  905. targetClass != securityCheckTargetClassCache) {
  906. Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
  907. securityCheckCache = caller;
  908. securityCheckTargetClassCache = targetClass;
  909. }
  910. }
  911. }
  912. }
  913. /*
  914. * Utility routine to paper over array type names
  915. */
  916. static String getTypeName(Class type) {
  917. if (type.isArray()) {
  918. try {
  919. Class cl = type;
  920. int dimensions = 0;
  921. while (cl.isArray()) {
  922. dimensions++;
  923. cl = cl.getComponentType();
  924. }
  925. StringBuffer sb = new StringBuffer();
  926. sb.append(cl.getName());
  927. for (int i = 0; i < dimensions; i++) {
  928. sb.append("[]");
  929. }
  930. return sb.toString();
  931. } catch (Throwable e) { /*FALLTHRU*/ }
  932. }
  933. return type.getName();
  934. }
  935. public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
  936. if (annotationClass == null)
  937. throw new NullPointerException();
  938. return (T) declaredAnnotations().get(annotationClass);
  939. }
  940. private static final Annotation[] EMPTY_ANNOTATION_ARRAY=new Annotation[0];
  941. public Annotation[] getDeclaredAnnotations() {
  942. return declaredAnnotations().values().toArray(EMPTY_ANNOTATION_ARRAY);
  943. }
  944. private transient Map<Class, Annotation> declaredAnnotations;
  945. private synchronized Map<Class, Annotation> declaredAnnotations() {
  946. if (declaredAnnotations == null) {
  947. declaredAnnotations = AnnotationParser.parseAnnotations(
  948. annotations, sun.misc.SharedSecrets.getJavaLangAccess().
  949. getConstantPool(getDeclaringClass()),
  950. getDeclaringClass());
  951. }
  952. return declaredAnnotations;
  953. }
  954. }