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