Source for java.lang.reflect.Field

   1: /* java.lang.reflect.Field - reflection of Java fields
   2:    Copyright (C) 1998, 2001, 2005, 2006 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10:  
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.lang.reflect;
  40: 
  41: import gnu.java.lang.ClassHelper;
  42: 
  43: import gnu.java.lang.reflect.FieldSignatureParser;
  44: 
  45: /**
  46:  * The Field class represents a member variable of a class. It also allows
  47:  * dynamic access to a member, via reflection. This works for both
  48:  * static and instance fields. Operations on Field objects know how to
  49:  * do widening conversions, but throw {@link IllegalArgumentException} if
  50:  * a narrowing conversion would be necessary. You can query for information
  51:  * on this Field regardless of location, but get and set access may be limited
  52:  * by Java language access controls. If you can't do it in the compiler, you
  53:  * can't normally do it here either.<p>
  54:  *
  55:  * <B>Note:</B> This class returns and accepts types as Classes, even
  56:  * primitive types; there are Class types defined that represent each
  57:  * different primitive type.  They are <code>java.lang.Boolean.TYPE,
  58:  * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
  59:  * byte.class</code>, etc.  These are not to be confused with the
  60:  * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
  61:  * real classes.<p>
  62:  *
  63:  * Also note that this is not a serializable class.  It is entirely feasible
  64:  * to make it serializable using the Externalizable interface, but this is
  65:  * on Sun, not me.
  66:  *
  67:  * @author John Keiser
  68:  * @author Eric Blake <ebb9@email.byu.edu>
  69:  * @author Per Bothner <bothner@cygnus.com>
  70:  * @see Member
  71:  * @see Class
  72:  * @see Class#getField(String)
  73:  * @see Class#getDeclaredField(String)
  74:  * @see Class#getFields()
  75:  * @see Class#getDeclaredFields()
  76:  * @since 1.1
  77:  * @status updated to 1.4
  78:  */
  79: public final class Field
  80:   extends AccessibleObject implements Member
  81: {
  82:   private Class declaringClass;
  83:   private String name;
  84: 
  85:   // Offset in bytes from the start of declaringClass's fields array.
  86:   private int offset;
  87: 
  88:   // The Class (or primitive TYPE) of this field.
  89:   private Class type;
  90: 
  91:   private static final int FIELD_MODIFIERS
  92:     = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
  93:       | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
  94:       | Modifier.VOLATILE;
  95: 
  96:   // This is instantiated by Class sometimes, but it uses C++ and
  97:   // avoids the Java protection check.
  98:   Field ()
  99:   {
 100:   }
 101: 
 102:   /**
 103:    * Gets the class that declared this field, or the class where this field
 104:    * is a non-inherited member.
 105:    * @return the class that declared this member
 106:    */
 107:   public Class getDeclaringClass()
 108:   {
 109:     return declaringClass;
 110:   }
 111: 
 112:   /**
 113:    * Gets the name of this field.
 114:    * @return the name of this field
 115:    */
 116:   public native String getName();
 117: 
 118:   /**
 119:    * Return the raw modifiers for this field.
 120:    * @return the field's modifiers
 121:    */
 122:   private native int getModifiersInternal();
 123: 
 124:   /**
 125:    * Gets the modifiers this field uses.  Use the <code>Modifier</code>
 126:    * class to interpret the values.  A field can only have a subset of the
 127:    * following modifiers: public, private, protected, static, final,
 128:    * transient, and volatile.
 129:    *
 130:    * @return an integer representing the modifiers to this Member
 131:    * @see Modifier
 132:    */
 133:   public int getModifiers()
 134:   {
 135:     return getModifiersInternal() & FIELD_MODIFIERS;
 136:   }
 137: 
 138:   /**
 139:    * Return true if this field is synthetic, false otherwise.
 140:    * @since 1.5
 141:    */
 142:   public boolean isSynthetic()
 143:   {
 144:     return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
 145:   }
 146: 
 147:   /**
 148:    * Return true if this field represents an enum constant,
 149:    * false otherwise.
 150:    * @since 1.5
 151:    */
 152:   public boolean isEnumConstant()
 153:   {
 154:     return (getModifiersInternal() & Modifier.ENUM) != 0;
 155:   }
 156: 
 157:   /**
 158:    * Gets the type of this field.
 159:    * @return the type of this field
 160:    */
 161:   public native Class getType();
 162: 
 163:   /**
 164:    * Compare two objects to see if they are semantically equivalent.
 165:    * Two Fields are semantically equivalent if they have the same declaring
 166:    * class, name, and type. Since you can't creat a Field except through
 167:    * the VM, this is just the == relation.
 168:    *
 169:    * @param o the object to compare to
 170:    * @return <code>true</code> if they are equal; <code>false</code> if not
 171:    */
 172:   public boolean equals (Object fld)
 173:   {
 174:     if (! (fld instanceof Field))
 175:       return false;
 176:     Field f = (Field) fld;
 177:     return declaringClass == f.declaringClass && offset == f.offset;
 178:   }
 179: 
 180:   /**
 181:    * Get the hash code for the Field. The Field hash code is the hash code
 182:    * of its name XOR'd with the hash code of its class name.
 183:    *
 184:    * @return the hash code for the object.
 185:    */
 186:   public int hashCode()
 187:   {
 188:     return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
 189:   }
 190: 
 191:   /**
 192:    * Get a String representation of the Field. A Field's String
 193:    * representation is "&lt;modifiers&gt; &lt;type&gt;
 194:    * &lt;class&gt;.&lt;fieldname&gt;".<br> Example:
 195:    * <code>public transient boolean gnu.parse.Parser.parseComplete</code>
 196:    *
 197:    * @return the String representation of the Field
 198:    */
 199:   public String toString ()
 200:   {
 201:     StringBuffer sbuf = new StringBuffer ();
 202:     int mods = getModifiers();
 203:     if (mods != 0)
 204:       {
 205:     Modifier.toString(mods, sbuf);
 206:     sbuf.append(' ');
 207:       }
 208:     Method.appendClassName (sbuf, getType ());
 209:     sbuf.append(' ');
 210:     Method.appendClassName (sbuf, getDeclaringClass());
 211:     sbuf.append('.');
 212:     sbuf.append(getName());
 213:     return sbuf.toString();
 214:   }
 215: 
 216:   public String toGenericString()
 217:   {
 218:     StringBuilder sb = new StringBuilder(64);
 219:     Modifier.toString(getModifiers(), sb).append(' ');
 220:     sb.append(getGenericType()).append(' ');
 221:     sb.append(getDeclaringClass().getName()).append('.');
 222:     sb.append(getName());
 223:     return sb.toString();
 224:   }
 225: 
 226:   /**
 227:    * Get the value of this Field.  If it is primitive, it will be wrapped
 228:    * in the appropriate wrapper type (boolean = java.lang.Boolean).<p>
 229:    *
 230:    * If the field is static, <code>o</code> will be ignored. Otherwise, if
 231:    * <code>o</code> is null, you get a <code>NullPointerException</code>,
 232:    * and if it is incompatible with the declaring class of the field, you
 233:    * get an <code>IllegalArgumentException</code>.<p>
 234:    *
 235:    * Next, if this Field enforces access control, your runtime context is
 236:    * evaluated, and you may have an <code>IllegalAccessException</code> if
 237:    * you could not access this field in similar compiled code. If the field
 238:    * is static, and its class is uninitialized, you trigger class
 239:    * initialization, which may end in a
 240:    * <code>ExceptionInInitializerError</code>.<p>
 241:    *
 242:    * Finally, the field is accessed, and primitives are wrapped (but not
 243:    * necessarily in new objects). This method accesses the field of the
 244:    * declaring class, even if the instance passed in belongs to a subclass
 245:    * which declares another field to hide this one.
 246:    *
 247:    * @param o the object to get the value of this Field from
 248:    * @return the value of the Field
 249:    * @throws IllegalAccessException if you could not normally access this field
 250:    *         (i.e. it is not public)
 251:    * @throws IllegalArgumentException if <code>o</code> is not an instance of
 252:    *         the class or interface declaring this field
 253:    * @throws NullPointerException if <code>o</code> is null and this field
 254:    *         requires an instance
 255:    * @throws ExceptionInInitializerError if accessing a static field triggered
 256:    *         class initialization, which then failed
 257:    * @see #getBoolean(Object)
 258:    * @see #getByte(Object)
 259:    * @see #getChar(Object)
 260:    * @see #getShort(Object)
 261:    * @see #getInt(Object)
 262:    * @see #getLong(Object)
 263:    * @see #getFloat(Object)
 264:    * @see #getDouble(Object)
 265:    */
 266:   public Object get(Object obj)
 267:     throws IllegalAccessException
 268:   {
 269:     return get(null, obj);
 270:   }
 271: 
 272:   /**
 273:    * Get the value of this boolean Field. If the field is static,
 274:    * <code>o</code> will be ignored.
 275:    *
 276:    * @param o the object to get the value of this Field from
 277:    * @return the value of the Field
 278:    * @throws IllegalAccessException if you could not normally access this field
 279:    *         (i.e. it is not public)
 280:    * @throws IllegalArgumentException if this is not a boolean field of
 281:    *         <code>o</code>, or if <code>o</code> is not an instance of the
 282:    *         declaring class of this field
 283:    * @throws NullPointerException if <code>o</code> is null and this field
 284:    *         requires an instance
 285:    * @throws ExceptionInInitializerError if accessing a static field triggered
 286:    *         class initialization, which then failed
 287:    * @see #get(Object)
 288:    */
 289:   public boolean getBoolean(Object obj)
 290:     throws IllegalAccessException
 291:   {
 292:     return getBoolean(null, obj);
 293:   }
 294: 
 295:   /**
 296:    * Get the value of this byte Field. If the field is static,
 297:    * <code>o</code> will be ignored.
 298:    *
 299:    * @param o the object to get the value of this Field from
 300:    * @return the value of the Field
 301:    * @throws IllegalAccessException if you could not normally access this field
 302:    *         (i.e. it is not public)
 303:    * @throws IllegalArgumentException if this is not a byte field of
 304:    *         <code>o</code>, or if <code>o</code> is not an instance of the
 305:    *         declaring class of this field
 306:    * @throws NullPointerException if <code>o</code> is null and this field
 307:    *         requires an instance
 308:    * @throws ExceptionInInitializerError if accessing a static field triggered
 309:    *         class initialization, which then failed
 310:    * @see #get(Object)
 311:    */
 312:   public byte getByte(Object obj)
 313:     throws IllegalAccessException
 314:   {
 315:     return getByte(null, obj);
 316:   }
 317: 
 318:   /**
 319:    * Get the value of this Field as a char. If the field is static,
 320:    * <code>o</code> will be ignored.
 321:    *
 322:    * @throws IllegalAccessException if you could not normally access this field
 323:    *         (i.e. it is not public)
 324:    * @throws IllegalArgumentException if this is not a char field of
 325:    *         <code>o</code>, or if <code>o</code> is not an instance
 326:    *         of the declaring class of this field
 327:    * @throws NullPointerException if <code>o</code> is null and this field
 328:    *         requires an instance
 329:    * @throws ExceptionInInitializerError if accessing a static field triggered
 330:    *         class initialization, which then failed
 331:    * @see #get(Object)
 332:    */
 333:   public char getChar(Object obj)
 334:     throws IllegalAccessException
 335:   {
 336:     return getChar(null, obj);
 337:   }
 338: 
 339:   /**
 340:    * Get the value of this Field as a short. If the field is static,
 341:    * <code>o</code> will be ignored.
 342:    *
 343:    * @param o the object to get the value of this Field from
 344:    * @return the value of the Field
 345:    * @throws IllegalAccessException if you could not normally access this field
 346:    *         (i.e. it is not public)
 347:    * @throws IllegalArgumentException if this is not a byte or short
 348:    *         field of <code>o</code>, or if <code>o</code> is not an instance
 349:    *         of the declaring class of this field
 350:    * @throws NullPointerException if <code>o</code> is null and this field
 351:    *         requires an instance
 352:    * @throws ExceptionInInitializerError if accessing a static field triggered
 353:    *         class initialization, which then failed
 354:    * @see #get(Object)
 355:    */
 356:   public short getShort(Object obj)
 357:     throws IllegalAccessException
 358:   {
 359:     return getShort(null, obj);
 360:   }
 361: 
 362:   /**
 363:    * Get the value of this Field as an int. If the field is static,
 364:    * <code>o</code> will be ignored.
 365:    *
 366:    * @param o the object to get the value of this Field from
 367:    * @return the value of the Field
 368:    * @throws IllegalAccessException if you could not normally access this field
 369:    *         (i.e. it is not public)
 370:    * @throws IllegalArgumentException if this is not a byte, short, char, or
 371:    *         int field of <code>o</code>, or if <code>o</code> is not an
 372:    *         instance of the declaring class of this field
 373:    * @throws NullPointerException if <code>o</code> is null and this field
 374:    *         requires an instance
 375:    * @throws ExceptionInInitializerError if accessing a static field triggered
 376:    *         class initialization, which then failed
 377:    * @see #get(Object)
 378:    */
 379:   public int getInt(Object obj)
 380:     throws IllegalAccessException
 381:   {
 382:     return getInt(null, obj);
 383:   }
 384: 
 385:   /**
 386:    * Get the value of this Field as a long. If the field is static,
 387:    * <code>o</code> will be ignored.
 388:    *
 389:    * @param o the object to get the value of this Field from
 390:    * @return the value of the Field
 391:    * @throws IllegalAccessException if you could not normally access this field
 392:    *         (i.e. it is not public)
 393:    * @throws IllegalArgumentException if this is not a byte, short, char, int,
 394:    *         or long field of <code>o</code>, or if <code>o</code> is not an
 395:    *         instance of the declaring class of this field
 396:    * @throws NullPointerException if <code>o</code> is null and this field
 397:    *         requires an instance
 398:    * @throws ExceptionInInitializerError if accessing a static field triggered
 399:    *         class initialization, which then failed
 400:    * @see #get(Object)
 401:    */
 402:   public long getLong(Object obj)
 403:     throws IllegalAccessException
 404:   {
 405:     return getLong(null, obj);
 406:   }
 407: 
 408:   /**
 409:    * Get the value of this Field as a float. If the field is static,
 410:    * <code>o</code> will be ignored.
 411:    *
 412:    * @param o the object to get the value of this Field from
 413:    * @return the value of the Field
 414:    * @throws IllegalAccessException if you could not normally access this field
 415:    *         (i.e. it is not public)
 416:    * @throws IllegalArgumentException if this is not a byte, short, char, int,
 417:    *         long, or float field of <code>o</code>, or if <code>o</code> is
 418:    *         not an instance of the declaring class of this field
 419:    * @throws NullPointerException if <code>o</code> is null and this field
 420:    *         requires an instance
 421:    * @throws ExceptionInInitializerError if accessing a static field triggered
 422:    *         class initialization, which then failed
 423:    * @see #get(Object)
 424:    */
 425:   public float getFloat(Object obj)
 426:     throws IllegalAccessException
 427:   {
 428:     return getFloat(null, obj);
 429:   }
 430: 
 431:   /**
 432:    * Get the value of this Field as a double. If the field is static,
 433:    * <code>o</code> will be ignored.
 434:    *
 435:    * @param o the object to get the value of this Field from
 436:    * @return the value of the Field
 437:    * @throws IllegalAccessException if you could not normally access this field
 438:    *         (i.e. it is not public)
 439:    * @throws IllegalArgumentException if this is not a byte, short, char, int,
 440:    *         long, float, or double field of <code>o</code>, or if
 441:    *         <code>o</code> is not an instance of the declaring class of this
 442:    *         field
 443:    * @throws NullPointerException if <code>o</code> is null and this field
 444:    *         requires an instance
 445:    * @throws ExceptionInInitializerError if accessing a static field triggered
 446:    *         class initialization, which then failed
 447:    * @see #get(Object)
 448:    */
 449:   public double getDouble(Object obj)
 450:     throws IllegalAccessException
 451:   {
 452:     return getDouble(null, obj);
 453:   }
 454: 
 455:   private native boolean getBoolean (Class caller, Object obj)
 456:     throws IllegalArgumentException, IllegalAccessException;
 457: 
 458:   private native char getChar (Class caller, Object obj)
 459:     throws IllegalArgumentException, IllegalAccessException;
 460: 
 461:   private native byte getByte (Class caller, Object obj)
 462:     throws IllegalArgumentException, IllegalAccessException;
 463: 
 464:   private native short getShort (Class caller, Object obj)
 465:     throws IllegalArgumentException, IllegalAccessException;
 466: 
 467:   private native int getInt (Class caller, Object obj)
 468:     throws IllegalArgumentException, IllegalAccessException;
 469: 
 470:   private native long getLong (Class caller, Object obj)
 471:     throws IllegalArgumentException, IllegalAccessException;
 472: 
 473:   private native float getFloat (Class caller, Object obj)
 474:     throws IllegalArgumentException, IllegalAccessException;
 475: 
 476:   private native double getDouble (Class caller, Object obj)
 477:     throws IllegalArgumentException, IllegalAccessException;
 478: 
 479:   private native Object get (Class caller, Object obj)
 480:     throws IllegalArgumentException, IllegalAccessException;
 481: 
 482:   /**
 483:    * Set the value of this Field.  If it is a primitive field, the value
 484:    * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p>
 485:    *
 486:    * If the field is static, <code>o</code> will be ignored. Otherwise, if
 487:    * <code>o</code> is null, you get a <code>NullPointerException</code>,
 488:    * and if it is incompatible with the declaring class of the field, you
 489:    * get an <code>IllegalArgumentException</code>.<p>
 490:    *
 491:    * Next, if this Field enforces access control, your runtime context is
 492:    * evaluated, and you may have an <code>IllegalAccessException</code> if
 493:    * you could not access this field in similar compiled code. This also
 494:    * occurs whether or not there is access control if the field is final.
 495:    * If the field is primitive, and unwrapping your argument fails, you will
 496:    * get an <code>IllegalArgumentException</code>; likewise, this error
 497:    * happens if <code>value</code> cannot be cast to the correct object type.
 498:    * If the field is static, and its class is uninitialized, you trigger class
 499:    * initialization, which may end in a
 500:    * <code>ExceptionInInitializerError</code>.<p>
 501:    *
 502:    * Finally, the field is set with the widened value. This method accesses
 503:    * the field of the declaring class, even if the instance passed in belongs
 504:    * to a subclass which declares another field to hide this one.
 505:    *
 506:    * @param o the object to set this Field on
 507:    * @param value the value to set this Field to
 508:    * @throws IllegalAccessException if you could not normally access this field
 509:    *         (i.e. it is not public)
 510:    * @throws IllegalArgumentException if <code>value</code> cannot be
 511:    *         converted by a widening conversion to the underlying type of
 512:    *         the Field, or if <code>o</code> is not an instance of the class
 513:    *         declaring this field
 514:    * @throws NullPointerException if <code>o</code> is null and this field
 515:    *         requires an instance
 516:    * @throws ExceptionInInitializerError if accessing a static field triggered
 517:    *         class initialization, which then failed
 518:    * @see #setBoolean(Object, boolean)
 519:    * @see #setByte(Object, byte)
 520:    * @see #setChar(Object, char)
 521:    * @see #setShort(Object, short)
 522:    * @see #setInt(Object, int)
 523:    * @see #setLong(Object, long)
 524:    * @see #setFloat(Object, float)
 525:    * @see #setDouble(Object, double)
 526:    */
 527:   public void set(Object object, Object value)
 528:     throws IllegalAccessException
 529:   {
 530:     set(null, object, value);
 531:   }
 532: 
 533:   /**
 534:    * Set this boolean Field. If the field is static, <code>o</code> will be
 535:    * ignored.
 536:    *
 537:    * @param o the object to set this Field on
 538:    * @param value the value to set this Field to
 539:    * @throws IllegalAccessException if you could not normally access this field
 540:    *         (i.e. it is not public)
 541:    * @throws IllegalArgumentException if this is not a boolean field, or if
 542:    *         <code>o</code> is not an instance of the class declaring this
 543:    *         field
 544:    * @throws NullPointerException if <code>o</code> is null and this field
 545:    *         requires an instance
 546:    * @throws ExceptionInInitializerError if accessing a static field triggered
 547:    *         class initialization, which then failed
 548:    * @see #set(Object, Object)
 549:    */
 550:   public void setBoolean(Object obj, boolean b)
 551:     throws IllegalAccessException
 552:   {
 553:     setBoolean(null, obj, b, true);
 554:   }
 555: 
 556:   /**
 557:    * Set this byte Field. If the field is static, <code>o</code> will be
 558:    * ignored.
 559:    *
 560:    * @param o the object to set this Field on
 561:    * @param value the value to set this Field to
 562:    * @throws IllegalAccessException if you could not normally access this field
 563:    *         (i.e. it is not public)
 564:    * @throws IllegalArgumentException if this is not a byte, short, int, long,
 565:    *         float, or double field, or if <code>o</code> is not an instance
 566:    *         of the class declaring this field
 567:    * @throws NullPointerException if <code>o</code> is null and this field
 568:    *         requires an instance
 569:    * @throws ExceptionInInitializerError if accessing a static field triggered
 570:    *         class initialization, which then failed
 571:    * @see #set(Object, Object)
 572:    */
 573:   public void setByte(Object obj, byte b)
 574:     throws IllegalAccessException
 575:   {
 576:     setByte(null, obj, b, true);
 577:   }
 578: 
 579:   /**
 580:    * Set this char Field. If the field is static, <code>o</code> will be
 581:    * ignored.
 582:    *
 583:    * @param o the object to set this Field on
 584:    * @param value the value to set this Field to
 585:    * @throws IllegalAccessException if you could not normally access this field
 586:    *         (i.e. it is not public)
 587:    * @throws IllegalArgumentException if this is not a char, int, long,
 588:    *         float, or double field, or if <code>o</code> is not an instance
 589:    *         of the class declaring this field
 590:    * @throws NullPointerException if <code>o</code> is null and this field
 591:    *         requires an instance
 592:    * @throws ExceptionInInitializerError if accessing a static field triggered
 593:    *         class initialization, which then failed
 594:    * @see #set(Object, Object)
 595:    */
 596:   public void setChar(Object obj, char c)
 597:     throws IllegalAccessException
 598:   {
 599:     setChar(null, obj, c, true);
 600:   }
 601: 
 602:   /**
 603:    * Set this short Field. If the field is static, <code>o</code> will be
 604:    * ignored.
 605:    *
 606:    * @param o the object to set this Field on
 607:    * @param value the value to set this Field to
 608:    * @throws IllegalAccessException if you could not normally access this field
 609:    *         (i.e. it is not public)
 610:    * @throws IllegalArgumentException if this is not a short, int, long,
 611:    *         float, or double field, or if <code>o</code> is not an instance
 612:    *         of the class declaring this field
 613:    * @throws NullPointerException if <code>o</code> is null and this field
 614:    *         requires an instance
 615:    * @throws ExceptionInInitializerError if accessing a static field triggered
 616:    *         class initialization, which then failed
 617:    * @see #set(Object, Object)
 618:    */
 619:   public void setShort(Object obj,  short s)
 620:     throws IllegalAccessException
 621:   {
 622:     setShort(null, obj, s, true);
 623:   }
 624: 
 625:   /**
 626:    * Set this int Field. If the field is static, <code>o</code> will be
 627:    * ignored.
 628:    *
 629:    * @param o the object to set this Field on
 630:    * @param value the value to set this Field to
 631:    * @throws IllegalAccessException if you could not normally access this field
 632:    *         (i.e. it is not public)
 633:    * @throws IllegalArgumentException if this is not an int, long, float, or
 634:    *         double field, or if <code>o</code> is not an instance of the
 635:    *         class declaring this field
 636:    * @throws NullPointerException if <code>o</code> is null and this field
 637:    *         requires an instance
 638:    * @throws ExceptionInInitializerError if accessing a static field triggered
 639:    *         class initialization, which then failed
 640:    * @see #set(Object, Object)
 641:    */
 642:   public void setInt(Object obj, int i)
 643:     throws IllegalAccessException
 644:   {
 645:     setInt(null, obj, i, true);
 646:   }
 647: 
 648:   /**
 649:    * Set this long Field. If the field is static, <code>o</code> will be
 650:    * ignored.
 651:    *
 652:    * @param o the object to set this Field on
 653:    * @param value the value to set this Field to
 654:    * @throws IllegalAccessException if you could not normally access this field
 655:    *         (i.e. it is not public)
 656:    * @throws IllegalArgumentException if this is not a long, float, or double
 657:    *         field, or if <code>o</code> is not an instance of the class
 658:    *         declaring this field
 659:    * @throws NullPointerException if <code>o</code> is null and this field
 660:    *         requires an instance
 661:    * @throws ExceptionInInitializerError if accessing a static field triggered
 662:    *         class initialization, which then failed
 663:    * @see #set(Object, Object)
 664:    */
 665:   public void setLong(Object obj, long l)
 666:     throws IllegalArgumentException, IllegalAccessException
 667:   {
 668:     setLong(null, obj, l, true);
 669:   }
 670: 
 671:   /**
 672:    * Set this float Field. If the field is static, <code>o</code> will be
 673:    * ignored.
 674:    *
 675:    * @param o the object to set this Field on
 676:    * @param value the value to set this Field to
 677:    * @throws IllegalAccessException if you could not normally access this field
 678:    *         (i.e. it is not public)
 679:    * @throws IllegalArgumentException if this is not a float or long field, or
 680:    *         if <code>o</code> is not an instance of the class declaring this
 681:    *         field
 682:    * @throws NullPointerException if <code>o</code> is null and this field
 683:    *         requires an instance
 684:    * @throws ExceptionInInitializerError if accessing a static field triggered
 685:    *         class initialization, which then failed
 686:    * @see #set(Object, Object)
 687:    */
 688:   public void setFloat(Object obj, float f)
 689:     throws IllegalAccessException
 690:   {
 691:     setFloat(null, obj, f, true);
 692:   }
 693: 
 694:   /**
 695:    * Set this double Field. If the field is static, <code>o</code> will be
 696:    * ignored.
 697:    *
 698:    * @param o the object to set this Field on
 699:    * @param value the value to set this Field to
 700:    * @throws IllegalAccessException if you could not normally access this field
 701:    *         (i.e. it is not public)
 702:    * @throws IllegalArgumentException if this is not a double field, or if
 703:    *         <code>o</code> is not an instance of the class declaring this
 704:    *         field
 705:    * @throws NullPointerException if <code>o</code> is null and this field
 706:    *         requires an instance
 707:    * @throws ExceptionInInitializerError if accessing a static field triggered
 708:    *         class initialization, which then failed
 709:    * @see #set(Object, Object)
 710:    */
 711:   public void setDouble(Object obj, double d)
 712:     throws IllegalAccessException
 713:   {
 714:     setDouble(null, obj, d, true);
 715:   }
 716: 
 717:   /**
 718:    * Return the generic type of the field. If the field type is not a generic
 719:    * type, the method returns the same as <code>getType()</code>.
 720:    *
 721:    * @throws GenericSignatureFormatError if the generic signature does
 722:    *         not conform to the format specified in the Virtual Machine
 723:    *         specification, version 3.
 724:    * @since 1.5
 725:    */
 726:   public Type getGenericType()
 727:   {
 728:     String signature = getSignature();
 729:     if (signature == null)
 730:       return getType();
 731:     FieldSignatureParser p = new FieldSignatureParser(getDeclaringClass(),
 732:                                                       signature);
 733:     return p.getFieldType();
 734:   }
 735: 
 736:   /**
 737:    * Return the String in the Signature attribute for this field. If there
 738:    * is no Signature attribute, return null.
 739:    */
 740:   private String getSignature()
 741:   {
 742:     // FIXME: libgcj doesn't record Signature attributes yet.
 743:     return null;
 744:   }
 745: 
 746:   native void setByte (Class caller, Object obj, byte b, boolean checkFinal)
 747:     throws IllegalArgumentException, IllegalAccessException;
 748: 
 749:   native void setShort (Class caller, Object obj, short s, boolean checkFinal)
 750:     throws IllegalArgumentException, IllegalAccessException;
 751: 
 752:   native void setInt (Class caller, Object obj, int i, boolean checkFinal)  
 753:     throws IllegalArgumentException, IllegalAccessException;
 754: 
 755:   native void setLong (Class caller, Object obj, long l, boolean checkFinal)
 756:     throws IllegalArgumentException, IllegalAccessException;
 757: 
 758:   native void setFloat (Class caller, Object obj, float f, boolean checkFinal)
 759:     throws IllegalArgumentException, IllegalAccessException;
 760: 
 761:   native void setDouble (Class caller, Object obj, double d,
 762:              boolean checkFinal)
 763:     throws IllegalArgumentException, IllegalAccessException;
 764: 
 765:   native void setChar (Class caller, Object obj, char c, boolean checkFinal)
 766:     throws IllegalArgumentException, IllegalAccessException;
 767: 
 768:   native void setBoolean (Class caller, Object obj, boolean b,
 769:               boolean checkFinal)
 770:     throws IllegalArgumentException, IllegalAccessException;
 771: 
 772:   native void set (Class caller, Object obj, Object val, Class type, 
 773:            boolean checkFinal)
 774:     throws IllegalArgumentException, IllegalAccessException;
 775: 
 776:   private void set (Class caller, Object object, Object value)
 777:     throws IllegalArgumentException, IllegalAccessException
 778:   {
 779:     Class type = getType();
 780:     if (! type.isPrimitive())
 781:       set(caller, object, value, type, true);
 782:     else if (value instanceof Byte)
 783:       setByte(caller, object, ((Byte) value).byteValue(), true);
 784:     else if (value instanceof Short)
 785:       setShort (caller, object, ((Short) value).shortValue(), true);
 786:     else if (value instanceof Integer)
 787:       setInt(caller, object, ((Integer) value).intValue(), true);
 788:     else if (value instanceof Long)
 789:       setLong(caller, object, ((Long) value).longValue(), true);
 790:     else if (value instanceof Float)
 791:       setFloat(caller, object, ((Float) value).floatValue(), true);
 792:     else if (value instanceof Double)
 793:       setDouble(caller, object, ((Double) value).doubleValue(), true);
 794:     else if (value instanceof Character)
 795:       setChar(caller, object, ((Character) value).charValue(), true);
 796:     else if (value instanceof Boolean)
 797:       setBoolean(caller, object, ((Boolean) value).booleanValue(), true);
 798:     else
 799:       throw new IllegalArgumentException();
 800:   }
 801: }