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