• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 /*
18  * Copyright (C) 2008 The Android Open Source Project
19  *
20  * Licensed under the Apache License, Version 2.0 (the "License");
21  * you may not use this file except in compliance with the License.
22  * You may obtain a copy of the License at
23  *
24  *      http://www.apache.org/licenses/LICENSE-2.0
25  *
26  * Unless required by applicable law or agreed to in writing, software
27  * distributed under the License is distributed on an "AS IS" BASIS,
28  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29  * See the License for the specific language governing permissions and
30  * limitations under the License.
31  */
32 
33 package java.lang.reflect;
34 
35 import java.lang.annotation.Annotation;
36 import java.util.Comparator;
37 import org.apache.harmony.kernel.vm.StringUtils;
38 import org.apache.harmony.luni.lang.reflect.GenericSignatureParser;
39 import org.apache.harmony.luni.lang.reflect.Types;
40 
41 /**
42  * This class represents a field. Information about the field can be accessed,
43  * and the field's value can be accessed dynamically.
44  */
45 public final class Field extends AccessibleObject implements Member {
46 
47     /**
48      * Orders fields by their name and declaring class.
49      *
50      * @hide
51      */
52     public static final Comparator<Field> ORDER_BY_NAME_AND_DECLARING_CLASS
53             = new Comparator<Field>() {
54         @Override public int compare(Field a, Field b) {
55             int comparison = a.name.compareTo(b.name);
56             if (comparison != 0) {
57                 return comparison;
58             }
59 
60             return a.getDeclaringClass().getName().compareTo(b.getDeclaringClass().getName());
61         }
62     };
63 
64     private Class<?> declaringClass;
65 
66     private Class<?> type;
67 
68     private Type genericType;
69 
70     private volatile boolean genericTypesAreInitialized = false;
71 
72     private String name;
73 
74     private int slot;
75 
76     private static final char TYPE_BOOLEAN = 'Z';
77 
78     private static final char TYPE_BYTE = 'B';
79 
80     private static final char TYPE_CHAR = 'C';
81 
82     private static final char TYPE_SHORT = 'S';
83 
84     private static final char TYPE_INTEGER = 'I';
85 
86     private static final char TYPE_FLOAT = 'F';
87 
88     private static final char TYPE_LONG = 'J';
89 
90     private static final char TYPE_DOUBLE = 'D';
91 
92     /**
93      * Construct a clone of the given instance.
94      *
95      * @param orig non-null; the original instance to clone
96      */
Field(Field orig)97     /*package*/ Field(Field orig) {
98         this(orig.declaringClass, orig.type, orig.name, orig.slot);
99 
100         // Copy the accessible flag.
101         if (orig.flag) {
102             this.flag = true;
103         }
104     }
105 
Field(Class<?> declaringClass, Class<?> type, String name, int slot)106     private Field(Class<?> declaringClass, Class<?> type, String name, int slot) {
107         this.declaringClass = declaringClass;
108         this.type = type;
109         this.name = name;
110         this.slot = slot;
111     }
112 
initGenericType()113     private synchronized void initGenericType() {
114         if (!genericTypesAreInitialized) {
115             String signatureAttribute = getSignatureAttribute();
116             GenericSignatureParser parser = new GenericSignatureParser(
117                     declaringClass.getClassLoader());
118             parser.parseForField(this.declaringClass, signatureAttribute);
119             genericType = parser.fieldType;
120             if (genericType == null) {
121                 genericType = getType();
122             }
123             genericTypesAreInitialized = true;
124         }
125     }
126 
127     /** {@inheritDoc} */
128     @Override
getSignatureAttribute()129     /* package */String getSignatureAttribute() {
130         Object[] annotation = getSignatureAnnotation(declaringClass, slot);
131 
132         if (annotation == null) {
133             return null;
134         }
135 
136         return StringUtils.combineStrings(annotation);
137     }
138 
139     /**
140      * Get the Signature annotation for this field. Returns null if not found.
141      */
getSignatureAnnotation(Class declaringClass, int slot)142     native private Object[] getSignatureAnnotation(Class declaringClass, int slot);
143 
144     /**
145      * Indicates whether or not this field is synthetic.
146      *
147      * @return {@code true} if this field is synthetic, {@code false} otherwise
148      */
isSynthetic()149     public boolean isSynthetic() {
150         int flags = getFieldModifiers(declaringClass, slot);
151         return (flags & Modifier.SYNTHETIC) != 0;
152     }
153 
154     /**
155      * Returns the string representation of this field, including the field's
156      * generic type.
157      *
158      * @return the string representation of this field
159      */
toGenericString()160     public String toGenericString() {
161         StringBuilder sb = new StringBuilder(80);
162         // append modifiers if any
163         int modifier = getModifiers();
164         if (modifier != 0) {
165             sb.append(Modifier.toString(modifier)).append(' ');
166         }
167         // append generic type
168         appendGenericType(sb, getGenericType());
169         sb.append(' ');
170         // append full field name
171         sb.append(getDeclaringClass().getName()).append('.').append(getName());
172         return sb.toString();
173     }
174 
175     /**
176      * Indicates whether or not this field is an enumeration constant.
177      *
178      * @return {@code true} if this field is an enumeration constant, {@code
179      *         false} otherwise
180      */
isEnumConstant()181     public boolean isEnumConstant() {
182         int flags = getFieldModifiers(declaringClass, slot);
183         return (flags & Modifier.ENUM) != 0;
184     }
185 
186     /**
187      * Returns the generic type of this field.
188      *
189      * @return the generic type
190      * @throws GenericSignatureFormatError
191      *             if the generic field signature is invalid
192      * @throws TypeNotPresentException
193      *             if the generic type points to a missing type
194      * @throws MalformedParameterizedTypeException
195      *             if the generic type points to a type that cannot be
196      *             instantiated for some reason
197      */
getGenericType()198     public Type getGenericType() {
199         initGenericType();
200         return Types.getType(genericType);
201     }
202 
getDeclaredAnnotations()203     @Override public Annotation[] getDeclaredAnnotations() {
204         return getDeclaredAnnotations(declaringClass, slot);
205     }
getDeclaredAnnotations(Class declaringClass, int slot)206     private static native Annotation[] getDeclaredAnnotations(Class declaringClass, int slot);
207 
getAnnotation(Class<A> annotationType)208     @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
209         if (annotationType == null) {
210             throw new NullPointerException("annotationType == null");
211         }
212         return getAnnotation(declaringClass, slot, annotationType);
213     }
getAnnotation( Class<?> declaringClass, int slot, Class<A> annotationType)214     private static native <A extends Annotation> A getAnnotation(
215             Class<?> declaringClass, int slot, Class<A> annotationType);
216 
isAnnotationPresent(Class<? extends Annotation> annotationType)217     @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
218         if (annotationType == null) {
219             throw new NullPointerException("annotationType == null");
220         }
221         return isAnnotationPresent(declaringClass, slot, annotationType);
222     }
isAnnotationPresent( Class<?> declaringClass, int slot, Class<? extends Annotation> annotationType)223     private static native boolean isAnnotationPresent(
224             Class<?> declaringClass, int slot, Class<? extends Annotation> annotationType);
225 
226     /**
227      * Indicates whether or not the specified {@code object} is equal to this
228      * field. To be equal, the specified object must be an instance of
229      * {@code Field} with the same declaring class, type and name as this field.
230      *
231      * @param object
232      *            the object to compare
233      * @return {@code true} if the specified object is equal to this method,
234      *         {@code false} otherwise
235      * @see #hashCode
236      */
237     @Override
equals(Object object)238     public boolean equals(Object object) {
239         return object instanceof Field && toString().equals(object.toString());
240     }
241 
242     /**
243      * Returns the value of the field in the specified object. This reproduces
244      * the effect of {@code object.fieldName}
245      *
246      * <p>If the type of this field is a primitive type, the field value is
247      * automatically boxed.
248      *
249      * <p>If this field is static, the object argument is ignored.
250      * Otherwise, if the object is null, a NullPointerException is thrown. If
251      * the object is not an instance of the declaring class of the method, an
252      * IllegalArgumentException is thrown.
253      *
254      * <p>If this Field object is enforcing access control (see AccessibleObject)
255      * and this field is not accessible from the current context, an
256      * IllegalAccessException is thrown.
257      *
258      * @param object
259      *            the object to access
260      * @return the field value, possibly boxed
261      * @throws NullPointerException
262      *             if the object is {@code null} and the field is non-static
263      * @throws IllegalArgumentException
264      *             if the object is not compatible with the declaring class
265      * @throws IllegalAccessException
266      *             if this field is not accessible
267      */
get(Object object)268     public Object get(Object object) throws IllegalAccessException, IllegalArgumentException {
269         return getField(object, declaringClass, type, slot, flag);
270     }
271 
272     /**
273      * Returns the value of the field in the specified object as a {@code
274      * boolean}. This reproduces the effect of {@code object.fieldName}
275      * <p>
276      * If this field is static, the object argument is ignored.
277      * Otherwise, if the object is {@code null}, a NullPointerException is
278      * thrown. If the object is not an instance of the declaring class of the
279      * method, an IllegalArgumentException is thrown.
280      * <p>
281      * If this Field object is enforcing access control (see AccessibleObject)
282      * and this field is not accessible from the current context, an
283      * IllegalAccessException is thrown.
284      *
285      * @param object
286      *            the object to access
287      * @return the field value
288      * @throws NullPointerException
289      *             if the object is {@code null} and the field is non-static
290      * @throws IllegalArgumentException
291      *             if the object is not compatible with the declaring class
292      * @throws IllegalAccessException
293      *             if this field is not accessible
294      */
getBoolean(Object object)295     public boolean getBoolean(Object object) throws IllegalAccessException,
296             IllegalArgumentException {
297         return getZField(object, declaringClass, type, slot, flag, TYPE_BOOLEAN);
298     }
299 
300     /**
301      * Returns the value of the field in the specified object as a {@code byte}.
302      * This reproduces the effect of {@code object.fieldName}
303      * <p>
304      * If this field is static, the object argument is ignored.
305      * Otherwise, if the object is {@code null}, a NullPointerException is
306      * thrown. If the object is not an instance of the declaring class of the
307      * method, an IllegalArgumentException is thrown.
308      * <p>
309      * If this Field object is enforcing access control (see AccessibleObject)
310      * and this field is not accessible from the current context, an
311      * IllegalAccessException is thrown.
312      *
313      * @param object
314      *            the object to access
315      * @return the field value
316      * @throws NullPointerException
317      *             if the object is {@code null} and the field is non-static
318      * @throws IllegalArgumentException
319      *             if the object is not compatible with the declaring class
320      * @throws IllegalAccessException
321      *             if this field is not accessible
322      */
getByte(Object object)323     public byte getByte(Object object) throws IllegalAccessException, IllegalArgumentException {
324         return getBField(object, declaringClass, type, slot, flag, TYPE_BYTE);
325     }
326 
327     /**
328      * Returns the value of the field in the specified object as a {@code char}.
329      * This reproduces the effect of {@code object.fieldName}
330      * <p>
331      * If this field is static, the object argument is ignored.
332      * Otherwise, if the object is {@code null}, a NullPointerException is
333      * thrown. If the object is not an instance of the declaring class of the
334      * method, an IllegalArgumentException is thrown.
335      * <p>
336      * If this Field object is enforcing access control (see AccessibleObject)
337      * and this field is not accessible from the current context, an
338      * IllegalAccessException is thrown.
339      *
340      * @param object
341      *            the object to access
342      * @return the field value
343      * @throws NullPointerException
344      *             if the object is {@code null} and the field is non-static
345      * @throws IllegalArgumentException
346      *             if the object is not compatible with the declaring class
347      * @throws IllegalAccessException
348      *             if this field is not accessible
349      */
getChar(Object object)350     public char getChar(Object object) throws IllegalAccessException, IllegalArgumentException {
351         return getCField(object, declaringClass, type, slot, flag, TYPE_CHAR);
352     }
353 
354     /**
355      * Returns the class that declares this field.
356      *
357      * @return the declaring class
358      */
getDeclaringClass()359     public Class<?> getDeclaringClass() {
360         return declaringClass;
361     }
362 
363     /**
364      * Returns the value of the field in the specified object as a {@code
365      * double}. This reproduces the effect of {@code object.fieldName}
366      * <p>
367      * If this field is static, the object argument is ignored.
368      * Otherwise, if the object is {@code null}, a NullPointerException is
369      * thrown. If the object is not an instance of the declaring class of the
370      * method, an IllegalArgumentException is thrown.
371      * <p>
372      * If this Field object is enforcing access control (see AccessibleObject)
373      * and this field is not accessible from the current context, an
374      * IllegalAccessException is thrown.
375      *
376      * @param object
377      *            the object to access
378      * @return the field value
379      * @throws NullPointerException
380      *             if the object is {@code null} and the field is non-static
381      * @throws IllegalArgumentException
382      *             if the object is not compatible with the declaring class
383      * @throws IllegalAccessException
384      *             if this field is not accessible
385      */
getDouble(Object object)386     public double getDouble(Object object) throws IllegalAccessException, IllegalArgumentException {
387         return getDField(object, declaringClass, type, slot, flag, TYPE_DOUBLE);
388     }
389 
390     /**
391      * Returns the value of the field in the specified object as a {@code float}
392      * . This reproduces the effect of {@code object.fieldName}
393      * <p>
394      * If this field is static, the object argument is ignored.
395      * Otherwise, if the object is {@code null}, a NullPointerException is
396      * thrown. If the object is not an instance of the declaring class of the
397      * method, an IllegalArgumentException is thrown.
398      * <p>
399      * If this Field object is enforcing access control (see AccessibleObject)
400      * and this field is not accessible from the current context, an
401      * IllegalAccessException is thrown.
402      *
403      * @param object
404      *            the object to access
405      * @return the field value
406      * @throws NullPointerException
407      *             if the object is {@code null} and the field is non-static
408      * @throws IllegalArgumentException
409      *             if the object is not compatible with the declaring class
410      * @throws IllegalAccessException
411      *             if this field is not accessible
412      */
getFloat(Object object)413     public float getFloat(Object object) throws IllegalAccessException, IllegalArgumentException {
414         return getFField(object, declaringClass, type, slot, flag, TYPE_FLOAT);
415     }
416 
417     /**
418      * Returns the value of the field in the specified object as an {@code int}.
419      * This reproduces the effect of {@code object.fieldName}
420      * <p>
421      * If this field is static, the object argument is ignored.
422      * Otherwise, if the object is {@code null}, a NullPointerException is
423      * thrown. If the object is not an instance of the declaring class of the
424      * method, an IllegalArgumentException is thrown.
425      * <p>
426      * If this Field object is enforcing access control (see AccessibleObject)
427      * and this field is not accessible from the current context, an
428      * IllegalAccessException is thrown.
429      *
430      * @param object
431      *            the object to access
432      * @return the field value
433      * @throws NullPointerException
434      *             if the object is {@code null} and the field is non-static
435      * @throws IllegalArgumentException
436      *             if the object is not compatible with the declaring class
437      * @throws IllegalAccessException
438      *             if this field is not accessible
439      */
getInt(Object object)440     public int getInt(Object object) throws IllegalAccessException, IllegalArgumentException {
441         return getIField(object, declaringClass, type, slot, flag, TYPE_INTEGER);
442     }
443 
444     /**
445      * Returns the value of the field in the specified object as a {@code long}.
446      * This reproduces the effect of {@code object.fieldName}
447      * <p>
448      * If this field is static, the object argument is ignored.
449      * Otherwise, if the object is {@code null}, a NullPointerException is
450      * thrown. If the object is not an instance of the declaring class of the
451      * method, an IllegalArgumentException is thrown.
452      * <p>
453      * If this Field object is enforcing access control (see AccessibleObject)
454      * and this field is not accessible from the current context, an
455      * IllegalAccessException is thrown.
456      *
457      * @param object
458      *            the object to access
459      * @return the field value
460      * @throws NullPointerException
461      *             if the object is {@code null} and the field is non-static
462      * @throws IllegalArgumentException
463      *             if the object is not compatible with the declaring class
464      * @throws IllegalAccessException
465      *             if this field is not accessible
466      */
getLong(Object object)467     public long getLong(Object object) throws IllegalAccessException, IllegalArgumentException {
468         return getJField(object, declaringClass, type, slot, flag, TYPE_LONG);
469     }
470 
471     /**
472      * Returns the modifiers for this field. The {@link Modifier} class should
473      * be used to decode the result.
474      *
475      * @return the modifiers for this field
476      * @see Modifier
477      */
getModifiers()478     public int getModifiers() {
479         return getFieldModifiers(declaringClass, slot);
480     }
481 
getFieldModifiers(Class<?> declaringClass, int slot)482     private native int getFieldModifiers(Class<?> declaringClass, int slot);
483 
484     /**
485      * Returns the name of this field.
486      *
487      * @return the name of this field
488      */
getName()489     public String getName() {
490         return name;
491     }
492 
493     /**
494      * Returns the value of the field in the specified object as a {@code short}
495      * . This reproduces the effect of {@code object.fieldName}
496      * <p>
497      * If this field is static, the object argument is ignored.
498      * Otherwise, if the object is {@code null}, a NullPointerException is
499      * thrown. If the object is not an instance of the declaring class of the
500      * method, an IllegalArgumentException is thrown.
501      * <p>
502      * If this Field object is enforcing access control (see AccessibleObject)
503      * and this field is not accessible from the current context, an
504      * IllegalAccessException is thrown.
505      *
506      * @param object
507      *            the object to access
508      * @return the field value
509      * @throws NullPointerException
510      *             if the object is {@code null} and the field is non-static
511      * @throws IllegalArgumentException
512      *             if the object is not compatible with the declaring class
513      * @throws IllegalAccessException
514      *             if this field is not accessible
515      */
getShort(Object object)516     public short getShort(Object object) throws IllegalAccessException, IllegalArgumentException {
517         return getSField(object, declaringClass, type, slot, flag, TYPE_SHORT);
518     }
519 
520     /**
521      * Returns the constructor's signature in non-printable form. This is called
522      * (only) from IO native code and needed for deriving the serialVersionUID
523      * of the class
524      *
525      * @return the constructor's signature.
526      */
527     @SuppressWarnings("unused")
getSignature()528     private String getSignature() {
529         return getSignature(type);
530     }
531 
532     /**
533      * Return the {@link Class} associated with the type of this field.
534      *
535      * @return the type of this field
536      */
getType()537     public Class<?> getType() {
538         return type;
539     }
540 
541     /**
542      * Returns an integer hash code for this field. Objects which are equal
543      * return the same value for this method.
544      * <p>
545      * The hash code for a Field is the exclusive-or combination of the hash
546      * code of the field's name and the hash code of the name of its declaring
547      * class.
548      *
549      * @return the hash code for this field
550      * @see #equals
551      */
552     @Override
hashCode()553     public int hashCode() {
554         return name.hashCode() ^ getDeclaringClass().getName().hashCode();
555     }
556 
557     /**
558      * Sets the value of the field in the specified object to the value. This
559      * reproduces the effect of {@code object.fieldName = value}
560      *
561      * <p>If this field is static, the object argument is ignored.
562      * Otherwise, if the object is {@code null}, a NullPointerException is
563      * thrown. If the object is not an instance of the declaring class of the
564      * method, an IllegalArgumentException is thrown.
565      *
566      * <p>If this Field object is enforcing access control (see AccessibleObject)
567      * and this field is not accessible from the current context, an
568      * IllegalAccessException is thrown.
569      *
570      * <p>If the field type is a primitive type, the value is automatically
571      * unboxed. If the unboxing fails, an IllegalArgumentException is thrown. If
572      * the value cannot be converted to the field type via a widening
573      * conversion, an IllegalArgumentException is thrown.
574      *
575      * @param object
576      *            the object to access
577      * @param value
578      *            the new value
579      * @throws NullPointerException
580      *             if the object is {@code null} and the field is non-static
581      * @throws IllegalArgumentException
582      *             if the object is not compatible with the declaring class
583      * @throws IllegalAccessException
584      *             if this field is not accessible
585      */
set(Object object, Object value)586     public void set(Object object, Object value) throws IllegalAccessException,
587             IllegalArgumentException {
588         setField(object, declaringClass, type, slot, flag, value);
589     }
590 
591     /**
592      * Sets the value of the field in the specified object to the {@code
593      * boolean} value. This reproduces the effect of {@code object.fieldName =
594      * value}
595      * <p>
596      * If this field is static, the object argument is ignored.
597      * Otherwise, if the object is {@code null}, a NullPointerException is
598      * thrown. If the object is not an instance of the declaring class of the
599      * method, an IllegalArgumentException is thrown.
600      * <p>
601      * If this Field object is enforcing access control (see AccessibleObject)
602      * and this field is not accessible from the current context, an
603      * IllegalAccessException is thrown.
604      * <p>
605      * If the value cannot be converted to the field type via a widening
606      * conversion, an IllegalArgumentException is thrown.
607      *
608      * @param object
609      *            the object to access
610      * @param value
611      *            the new value
612      * @throws NullPointerException
613      *             if the object is {@code null} and the field is non-static
614      * @throws IllegalArgumentException
615      *             if the object is not compatible with the declaring class
616      * @throws IllegalAccessException
617      *             if this field is not accessible
618      */
setBoolean(Object object, boolean value)619     public void setBoolean(Object object, boolean value) throws IllegalAccessException,
620             IllegalArgumentException {
621         setZField(object, declaringClass, type, slot, flag, TYPE_BOOLEAN, value);
622     }
623 
624     /**
625      * Sets the value of the field in the specified object to the {@code byte}
626      * value. This reproduces the effect of {@code object.fieldName = value}
627      * <p>
628      * If this field is static, the object argument is ignored.
629      * Otherwise, if the object is {@code null}, a NullPointerException is
630      * thrown. If the object is not an instance of the declaring class of the
631      * method, an IllegalArgumentException is thrown.
632      * <p>
633      * If this Field object is enforcing access control (see AccessibleObject)
634      * and this field is not accessible from the current context, an
635      * IllegalAccessException is thrown.
636      * <p>
637      * If the value cannot be converted to the field type via a widening
638      * conversion, an IllegalArgumentException is thrown.
639      *
640      * @param object
641      *            the object to access
642      * @param value
643      *            the new value
644      * @throws NullPointerException
645      *             if the object is {@code null} and the field is non-static
646      * @throws IllegalArgumentException
647      *             if the object is not compatible with the declaring class
648      * @throws IllegalAccessException
649      *             if this field is not accessible
650      */
setByte(Object object, byte value)651     public void setByte(Object object, byte value) throws IllegalAccessException,
652             IllegalArgumentException {
653         setBField(object, declaringClass, type, slot, flag, TYPE_BYTE, value);
654     }
655 
656     /**
657      * Sets the value of the field in the specified object to the {@code char}
658      * value. This reproduces the effect of {@code object.fieldName = value}
659      * <p>
660      * If this field is static, the object argument is ignored.
661      * Otherwise, if the object is {@code null}, a NullPointerException is
662      * thrown. If the object is not an instance of the declaring class of the
663      * method, an IllegalArgumentException is thrown.
664      * <p>
665      * If this Field object is enforcing access control (see AccessibleObject)
666      * and this field is not accessible from the current context, an
667      * IllegalAccessException is thrown.
668      * <p>
669      * If the value cannot be converted to the field type via a widening
670      * conversion, an IllegalArgumentException is thrown.
671      *
672      * @param object
673      *            the object to access
674      * @param value
675      *            the new value
676      * @throws NullPointerException
677      *             if the object is {@code null} and the field is non-static
678      * @throws IllegalArgumentException
679      *             if the object is not compatible with the declaring class
680      * @throws IllegalAccessException
681      *             if this field is not accessible
682      */
setChar(Object object, char value)683     public void setChar(Object object, char value) throws IllegalAccessException,
684             IllegalArgumentException {
685         setCField(object, declaringClass, type, slot, flag, TYPE_CHAR, value);
686     }
687 
688     /**
689      * Sets the value of the field in the specified object to the {@code double}
690      * value. This reproduces the effect of {@code object.fieldName = value}
691      * <p>
692      * If this field is static, the object argument is ignored.
693      * Otherwise, if the object is {@code null}, a NullPointerException is
694      * thrown. If the object is not an instance of the declaring class of the
695      * method, an IllegalArgumentException is thrown.
696      * <p>
697      * If this Field object is enforcing access control (see AccessibleObject)
698      * and this field is not accessible from the current context, an
699      * IllegalAccessException is thrown.
700      * <p>
701      * If the value cannot be converted to the field type via a widening
702      * conversion, an IllegalArgumentException is thrown.
703      *
704      * @param object
705      *            the object to access
706      * @param value
707      *            the new value
708      * @throws NullPointerException
709      *             if the object is {@code null} and the field is non-static
710      * @throws IllegalArgumentException
711      *             if the object is not compatible with the declaring class
712      * @throws IllegalAccessException
713      *             if this field is not accessible
714      */
setDouble(Object object, double value)715     public void setDouble(Object object, double value) throws IllegalAccessException,
716             IllegalArgumentException {
717         setDField(object, declaringClass, type, slot, flag, TYPE_DOUBLE, value);
718     }
719 
720     /**
721      * Sets the value of the field in the specified object to the {@code float}
722      * value. This reproduces the effect of {@code object.fieldName = value}
723      * <p>
724      * If this field is static, the object argument is ignored.
725      * Otherwise, if the object is {@code null}, a NullPointerException is
726      * thrown. If the object is not an instance of the declaring class of the
727      * method, an IllegalArgumentException is thrown.
728      * <p>
729      * If this Field object is enforcing access control (see AccessibleObject)
730      * and this field is not accessible from the current context, an
731      * IllegalAccessException is thrown.
732      * <p>
733      * If the value cannot be converted to the field type via a widening
734      * conversion, an IllegalArgumentException is thrown.
735      *
736      * @param object
737      *            the object to access
738      * @param value
739      *            the new value
740      * @throws NullPointerException
741      *             if the object is {@code null} and the field is non-static
742      * @throws IllegalArgumentException
743      *             if the object is not compatible with the declaring class
744      * @throws IllegalAccessException
745      *             if this field is not accessible
746      */
setFloat(Object object, float value)747     public void setFloat(Object object, float value) throws IllegalAccessException,
748             IllegalArgumentException {
749         setFField(object, declaringClass, type, slot, flag, TYPE_FLOAT, value);
750     }
751 
752     /**
753      * Set the value of the field in the specified object to the {@code int}
754      * value. This reproduces the effect of {@code object.fieldName = value}
755      * <p>
756      * If this field is static, the object argument is ignored.
757      * Otherwise, if the object is {@code null}, a NullPointerException is
758      * thrown. If the object is not an instance of the declaring class of the
759      * method, an IllegalArgumentException is thrown.
760      * <p>
761      * If this Field object is enforcing access control (see AccessibleObject)
762      * and this field is not accessible from the current context, an
763      * IllegalAccessException is thrown.
764      * <p>
765      * If the value cannot be converted to the field type via a widening
766      * conversion, an IllegalArgumentException is thrown.
767      *
768      * @param object
769      *            the object to access
770      * @param value
771      *            the new value
772      * @throws NullPointerException
773      *             if the object is {@code null} and the field is non-static
774      * @throws IllegalArgumentException
775      *             if the object is not compatible with the declaring class
776      * @throws IllegalAccessException
777      *             if this field is not accessible
778      */
setInt(Object object, int value)779     public void setInt(Object object, int value) throws IllegalAccessException,
780             IllegalArgumentException {
781         setIField(object, declaringClass, type, slot, flag, TYPE_INTEGER, value);
782     }
783 
784     /**
785      * Sets the value of the field in the specified object to the {@code long}
786      * value. This reproduces the effect of {@code object.fieldName = value}
787      * <p>
788      * If this field is static, the object argument is ignored.
789      * Otherwise, if the object is {@code null}, a NullPointerException is
790      * thrown. If the object is not an instance of the declaring class of the
791      * method, an IllegalArgumentException is thrown.
792      * <p>
793      * If this Field object is enforcing access control (see AccessibleObject)
794      * and this field is not accessible from the current context, an
795      * IllegalAccessException is thrown.
796      * <p>
797      * If the value cannot be converted to the field type via a widening
798      * conversion, an IllegalArgumentException is thrown.
799      *
800      * @param object
801      *            the object to access
802      * @param value
803      *            the new value
804      * @throws NullPointerException
805      *             if the object is {@code null} and the field is non-static
806      * @throws IllegalArgumentException
807      *             if the object is not compatible with the declaring class
808      * @throws IllegalAccessException
809      *             if this field is not accessible
810      */
setLong(Object object, long value)811     public void setLong(Object object, long value) throws IllegalAccessException,
812             IllegalArgumentException {
813         setJField(object, declaringClass, type, slot, flag, TYPE_LONG, value);
814     }
815 
816     /**
817      * Sets the value of the field in the specified object to the {@code short}
818      * value. This reproduces the effect of {@code object.fieldName = value}
819      * <p>
820      * If this field is static, the object argument is ignored.
821      * Otherwise, if the object is {@code null}, a NullPointerException is
822      * thrown. If the object is not an instance of the declaring class of the
823      * method, an IllegalArgumentException is thrown.
824      * <p>
825      * If this Field object is enforcing access control (see AccessibleObject)
826      * and this field is not accessible from the current context, an
827      * IllegalAccessException is thrown.
828      * <p>
829      * If the value cannot be converted to the field type via a widening
830      * conversion, an IllegalArgumentException is thrown.
831      *
832      * @param object
833      *            the object to access
834      * @param value
835      *            the new value
836      * @throws NullPointerException
837      *             if the object is {@code null} and the field is non-static
838      * @throws IllegalArgumentException
839      *             if the object is not compatible with the declaring class
840      * @throws IllegalAccessException
841      *             if this field is not accessible
842      */
setShort(Object object, short value)843     public void setShort(Object object, short value) throws IllegalAccessException,
844             IllegalArgumentException {
845         setSField(object, declaringClass, type, slot, flag, TYPE_SHORT, value);
846     }
847 
848     /**
849      * Returns a string containing a concise, human-readable description of this
850      * field.
851      * <p>
852      * The format of the string is:
853      * <ol>
854      *   <li>modifiers (if any)
855      *   <li>type
856      *   <li>declaring class name
857      *   <li>'.'
858      *   <li>field name
859      * </ol>
860      * <p>
861      * For example: {@code public static java.io.InputStream
862      * java.lang.System.in}
863      *
864      * @return a printable representation for this field
865      */
866     @Override
toString()867     public String toString() {
868         StringBuilder result = new StringBuilder(Modifier.toString(getModifiers()));
869         if (result.length() != 0) {
870             result.append(' ');
871         }
872         appendTypeName(result, type);
873         result.append(' ');
874         appendTypeName(result, declaringClass);
875         result.append('.');
876         result.append(name);
877         return result.toString();
878     }
879 
getField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck)880     private native Object getField(Object o, Class<?> declaringClass, Class<?> type, int slot,
881             boolean noAccessCheck) throws IllegalAccessException;
882 
getDField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor)883     private native double getDField(Object o, Class<?> declaringClass, Class<?> type, int slot,
884             boolean noAccessCheck, char descriptor) throws IllegalAccessException;
885 
getIField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor)886     private native int getIField(Object o, Class<?> declaringClass, Class<?> type, int slot,
887             boolean noAccessCheck, char descriptor) throws IllegalAccessException;
888 
getJField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor)889     private native long getJField(Object o, Class<?> declaringClass, Class<?> type, int slot,
890             boolean noAccessCheck, char descriptor) throws IllegalAccessException;
891 
getZField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor)892     private native boolean getZField(Object o, Class<?> declaringClass, Class<?> type, int slot,
893             boolean noAccessCheck, char descriptor) throws IllegalAccessException;
894 
getFField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor)895     private native float getFField(Object o, Class<?> declaringClass, Class<?> type, int slot,
896             boolean noAccessCheck, char descriptor) throws IllegalAccessException;
897 
getCField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor)898     private native char getCField(Object o, Class<?> declaringClass, Class<?> type, int slot,
899             boolean noAccessCheck, char descriptor) throws IllegalAccessException;
900 
getSField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor)901     private native short getSField(Object o, Class<?> declaringClass, Class<?> type, int slot,
902             boolean noAccessCheck, char descriptor) throws IllegalAccessException;
903 
getBField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor)904     private native byte getBField(Object o, Class<?> declaringClass, Class<?> type, int slot,
905             boolean noAccessCheck, char descriptor) throws IllegalAccessException;
906 
setField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, Object value)907     private native void setField(Object o, Class<?> declaringClass, Class<?> type, int slot,
908             boolean noAccessCheck, Object value) throws IllegalAccessException;
909 
setDField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor, double v)910     private native void setDField(Object o, Class<?> declaringClass, Class<?> type, int slot,
911             boolean noAccessCheck, char descriptor, double v) throws IllegalAccessException;
912 
setIField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor, int i)913     private native void setIField(Object o, Class<?> declaringClass, Class<?> type, int slot,
914             boolean noAccessCheck, char descriptor, int i) throws IllegalAccessException;
915 
setJField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor, long j)916     private native void setJField(Object o, Class<?> declaringClass, Class<?> type, int slot,
917             boolean noAccessCheck, char descriptor, long j) throws IllegalAccessException;
918 
setZField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor, boolean z)919     private native void setZField(Object o, Class<?> declaringClass, Class<?> type, int slot,
920             boolean noAccessCheck, char descriptor, boolean z) throws IllegalAccessException;
921 
setFField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor, float f)922     private native void setFField(Object o, Class<?> declaringClass, Class<?> type, int slot,
923             boolean noAccessCheck, char descriptor, float f) throws IllegalAccessException;
924 
setCField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor, char c)925     private native void setCField(Object o, Class<?> declaringClass, Class<?> type, int slot,
926             boolean noAccessCheck, char descriptor, char c) throws IllegalAccessException;
927 
setSField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor, short s)928     private native void setSField(Object o, Class<?> declaringClass, Class<?> type, int slot,
929             boolean noAccessCheck, char descriptor, short s) throws IllegalAccessException;
930 
setBField(Object o, Class<?> declaringClass, Class<?> type, int slot, boolean noAccessCheck, char descriptor, byte b)931     private native void setBField(Object o, Class<?> declaringClass, Class<?> type, int slot,
932             boolean noAccessCheck, char descriptor, byte b) throws IllegalAccessException;
933 
934 }
935