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