GNU Classpath (0.95) | |
Frames | No Frames |
1: /* java.lang.reflect.Field - reflection of Java fields 2: Copyright (C) 1998, 2001, 2005 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: * @see Member 70: * @see Class 71: * @see Class#getField(String) 72: * @see Class#getDeclaredField(String) 73: * @see Class#getFields() 74: * @see Class#getDeclaredFields() 75: * @since 1.1 76: * @status updated to 1.4 77: */ 78: public final class Field 79: extends AccessibleObject implements Member 80: { 81: private Class declaringClass; 82: private String name; 83: private int slot; 84: 85: private static final int FIELD_MODIFIERS 86: = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED 87: | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT 88: | Modifier.VOLATILE; 89: 90: /** 91: * This class is uninstantiable except natively. 92: */ 93: private Field(Class declaringClass, String name, int slot) 94: { 95: this.declaringClass = declaringClass; 96: this.name = name; 97: this.slot = slot; 98: } 99: 100: /** 101: * Gets the class that declared this field, or the class where this field 102: * is a non-inherited member. 103: * @return the class that declared this member 104: */ 105: public Class<?> getDeclaringClass() 106: { 107: return declaringClass; 108: } 109: 110: /** 111: * Gets the name of this field. 112: * @return the name of this field 113: */ 114: public String getName() 115: { 116: return name; 117: } 118: 119: /** 120: * Return the raw modifiers for this field. 121: * @return the field's modifiers 122: */ 123: private native int getModifiersInternal(); 124: 125: /** 126: * Gets the modifiers this field uses. Use the <code>Modifier</code> 127: * class to interpret the values. A field can only have a subset of the 128: * following modifiers: public, private, protected, static, final, 129: * transient, and volatile. 130: * 131: * @return an integer representing the modifiers to this Member 132: * @see Modifier 133: */ 134: public int getModifiers() 135: { 136: return getModifiersInternal() & FIELD_MODIFIERS; 137: } 138: 139: /** 140: * Return true if this field is synthetic, false otherwise. 141: * @since 1.5 142: */ 143: public boolean isSynthetic() 144: { 145: return (getModifiersInternal() & Modifier.SYNTHETIC) != 0; 146: } 147: 148: /** 149: * Return true if this field represents an enum constant, 150: * false otherwise. 151: * @since 1.5 152: */ 153: public boolean isEnumConstant() 154: { 155: return (getModifiersInternal() & Modifier.ENUM) != 0; 156: } 157: 158: /** 159: * Gets the type of this field. 160: * @return the type of this field 161: */ 162: public native Class<?> getType(); 163: 164: /** 165: * Compare two objects to see if they are semantically equivalent. 166: * Two Fields are semantically equivalent if they have the same declaring 167: * class, name, and type. Since you can't creat a Field except through 168: * the VM, this is just the == relation. 169: * 170: * @param o the object to compare to 171: * @return <code>true</code> if they are equal; <code>false</code> if not 172: */ 173: public boolean equals(Object o) 174: { 175: if (!(o instanceof Field)) 176: return false; 177: Field that = (Field)o; 178: if (this.getDeclaringClass() != that.getDeclaringClass()) 179: return false; 180: if (!this.getName().equals(that.getName())) 181: return false; 182: if (this.getType() != that.getType()) 183: return false; 184: return true; 185: } 186: 187: /** 188: * Get the hash code for the Field. The Field hash code is the hash code 189: * of its name XOR'd with the hash code of its class name. 190: * 191: * @return the hash code for the object. 192: */ 193: public int hashCode() 194: { 195: return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); 196: } 197: 198: /** 199: * Get a String representation of the Field. A Field's String 200: * representation is "<modifiers> <type> 201: * <class>.<fieldname>".<br> Example: 202: * <code>public transient boolean gnu.parse.Parser.parseComplete</code> 203: * 204: * @return the String representation of the Field 205: */ 206: public String toString() 207: { 208: // 64 is a reasonable buffer initial size for field 209: StringBuilder sb = new StringBuilder(64); 210: Modifier.toString(getModifiers(), sb).append(' '); 211: sb.append(ClassHelper.getUserName(getType())).append(' '); 212: sb.append(getDeclaringClass().getName()).append('.'); 213: sb.append(getName()); 214: return sb.toString(); 215: } 216: 217: public String toGenericString() 218: { 219: StringBuilder sb = new StringBuilder(64); 220: Modifier.toString(getModifiers(), sb).append(' '); 221: sb.append(getGenericType()).append(' '); 222: sb.append(getDeclaringClass().getName()).append('.'); 223: sb.append(getName()); 224: return sb.toString(); 225: } 226: 227: /** 228: * Get the value of this Field. If it is primitive, it will be wrapped 229: * in the appropriate wrapper type (boolean = java.lang.Boolean).<p> 230: * 231: * If the field is static, <code>o</code> will be ignored. Otherwise, if 232: * <code>o</code> is null, you get a <code>NullPointerException</code>, 233: * and if it is incompatible with the declaring class of the field, you 234: * get an <code>IllegalArgumentException</code>.<p> 235: * 236: * Next, if this Field enforces access control, your runtime context is 237: * evaluated, and you may have an <code>IllegalAccessException</code> if 238: * you could not access this field in similar compiled code. If the field 239: * is static, and its class is uninitialized, you trigger class 240: * initialization, which may end in a 241: * <code>ExceptionInInitializerError</code>.<p> 242: * 243: * Finally, the field is accessed, and primitives are wrapped (but not 244: * necessarily in new objects). This method accesses the field of the 245: * declaring class, even if the instance passed in belongs to a subclass 246: * which declares another field to hide this one. 247: * 248: * @param o the object to get the value of this Field from 249: * @return the value of the Field 250: * @throws IllegalAccessException if you could not normally access this field 251: * (i.e. it is not public) 252: * @throws IllegalArgumentException if <code>o</code> is not an instance of 253: * the class or interface declaring this field 254: * @throws NullPointerException if <code>o</code> is null and this field 255: * requires an instance 256: * @throws ExceptionInInitializerError if accessing a static field triggered 257: * class initialization, which then failed 258: * @see #getBoolean(Object) 259: * @see #getByte(Object) 260: * @see #getChar(Object) 261: * @see #getShort(Object) 262: * @see #getInt(Object) 263: * @see #getLong(Object) 264: * @see #getFloat(Object) 265: * @see #getDouble(Object) 266: */ 267: public native Object get(Object o) 268: throws IllegalAccessException; 269: 270: /** 271: * Get the value of this boolean Field. If the field is static, 272: * <code>o</code> will be ignored. 273: * 274: * @param o the object to get the value of this Field from 275: * @return the value of the Field 276: * @throws IllegalAccessException if you could not normally access this field 277: * (i.e. it is not public) 278: * @throws IllegalArgumentException if this is not a boolean field of 279: * <code>o</code>, or if <code>o</code> is not an instance of the 280: * declaring class of this field 281: * @throws NullPointerException if <code>o</code> is null and this field 282: * requires an instance 283: * @throws ExceptionInInitializerError if accessing a static field triggered 284: * class initialization, which then failed 285: * @see #get(Object) 286: */ 287: public native boolean getBoolean(Object o) 288: throws IllegalAccessException; 289: 290: /** 291: * Get the value of this byte Field. If the field is static, 292: * <code>o</code> will be ignored. 293: * 294: * @param o the object to get the value of this Field from 295: * @return the value of the Field 296: * @throws IllegalAccessException if you could not normally access this field 297: * (i.e. it is not public) 298: * @throws IllegalArgumentException if this is not a byte field of 299: * <code>o</code>, or if <code>o</code> is not an instance of the 300: * declaring class of this field 301: * @throws NullPointerException if <code>o</code> is null and this field 302: * requires an instance 303: * @throws ExceptionInInitializerError if accessing a static field triggered 304: * class initialization, which then failed 305: * @see #get(Object) 306: */ 307: public native byte getByte(Object o) 308: throws IllegalAccessException; 309: 310: /** 311: * Get the value of this Field as a char. If the field is static, 312: * <code>o</code> will be ignored. 313: * 314: * @throws IllegalAccessException if you could not normally access this field 315: * (i.e. it is not public) 316: * @throws IllegalArgumentException if this is not a char field of 317: * <code>o</code>, or if <code>o</code> is not an instance 318: * of the declaring class of this field 319: * @throws NullPointerException if <code>o</code> is null and this field 320: * requires an instance 321: * @throws ExceptionInInitializerError if accessing a static field triggered 322: * class initialization, which then failed 323: * @see #get(Object) 324: */ 325: public native char getChar(Object o) 326: throws IllegalAccessException; 327: 328: /** 329: * Get the value of this Field as a short. If the field is static, 330: * <code>o</code> will be ignored. 331: * 332: * @param o the object to get the value of this Field from 333: * @return the value of the Field 334: * @throws IllegalAccessException if you could not normally access this field 335: * (i.e. it is not public) 336: * @throws IllegalArgumentException if this is not a byte or short 337: * field of <code>o</code>, or if <code>o</code> is not an instance 338: * of the declaring class of this field 339: * @throws NullPointerException if <code>o</code> is null and this field 340: * requires an instance 341: * @throws ExceptionInInitializerError if accessing a static field triggered 342: * class initialization, which then failed 343: * @see #get(Object) 344: */ 345: public native short getShort(Object o) 346: throws IllegalAccessException; 347: 348: /** 349: * Get the value of this Field as an int. If the field is static, 350: * <code>o</code> will be ignored. 351: * 352: * @param o the object to get the value of this Field from 353: * @return the value of the Field 354: * @throws IllegalAccessException if you could not normally access this field 355: * (i.e. it is not public) 356: * @throws IllegalArgumentException if this is not a byte, short, char, or 357: * int field of <code>o</code>, or if <code>o</code> is not an 358: * instance of the declaring class of this field 359: * @throws NullPointerException if <code>o</code> is null and this field 360: * requires an instance 361: * @throws ExceptionInInitializerError if accessing a static field triggered 362: * class initialization, which then failed 363: * @see #get(Object) 364: */ 365: public native int getInt(Object o) 366: throws IllegalAccessException; 367: 368: /** 369: * Get the value of this Field as a long. If the field is static, 370: * <code>o</code> will be ignored. 371: * 372: * @param o the object to get the value of this Field from 373: * @return the value of the Field 374: * @throws IllegalAccessException if you could not normally access this field 375: * (i.e. it is not public) 376: * @throws IllegalArgumentException if this is not a byte, short, char, int, 377: * or long field of <code>o</code>, or if <code>o</code> is not an 378: * instance of the declaring class of this field 379: * @throws NullPointerException if <code>o</code> is null and this field 380: * requires an instance 381: * @throws ExceptionInInitializerError if accessing a static field triggered 382: * class initialization, which then failed 383: * @see #get(Object) 384: */ 385: public native long getLong(Object o) 386: throws IllegalAccessException; 387: 388: /** 389: * Get the value of this Field as a float. If the field is static, 390: * <code>o</code> will be ignored. 391: * 392: * @param o the object to get the value of this Field from 393: * @return the value of the Field 394: * @throws IllegalAccessException if you could not normally access this field 395: * (i.e. it is not public) 396: * @throws IllegalArgumentException if this is not a byte, short, char, int, 397: * long, or float field of <code>o</code>, or if <code>o</code> is 398: * not an instance of the declaring class of this field 399: * @throws NullPointerException if <code>o</code> is null and this field 400: * requires an instance 401: * @throws ExceptionInInitializerError if accessing a static field triggered 402: * class initialization, which then failed 403: * @see #get(Object) 404: */ 405: public native float getFloat(Object o) 406: throws IllegalAccessException; 407: 408: /** 409: * Get the value of this Field as a double. 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, float, or double field of <code>o</code>, or if 418: * <code>o</code> is not an instance of the declaring class of this 419: * field 420: * @throws NullPointerException if <code>o</code> is null and this field 421: * requires an instance 422: * @throws ExceptionInInitializerError if accessing a static field triggered 423: * class initialization, which then failed 424: * @see #get(Object) 425: */ 426: public native double getDouble(Object o) 427: throws IllegalAccessException; 428: 429: /** 430: * Set the value of this Field. If it is a primitive field, the value 431: * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p> 432: * 433: * If the field is static, <code>o</code> will be ignored. Otherwise, if 434: * <code>o</code> is null, you get a <code>NullPointerException</code>, 435: * and if it is incompatible with the declaring class of the field, you 436: * get an <code>IllegalArgumentException</code>.<p> 437: * 438: * Next, if this Field enforces access control, your runtime context is 439: * evaluated, and you may have an <code>IllegalAccessException</code> if 440: * you could not access this field in similar compiled code. This also 441: * occurs whether or not there is access control if the field is final. 442: * If the field is primitive, and unwrapping your argument fails, you will 443: * get an <code>IllegalArgumentException</code>; likewise, this error 444: * happens if <code>value</code> cannot be cast to the correct object type. 445: * If the field is static, and its class is uninitialized, you trigger class 446: * initialization, which may end in a 447: * <code>ExceptionInInitializerError</code>.<p> 448: * 449: * Finally, the field is set with the widened value. This method accesses 450: * the field of the declaring class, even if the instance passed in belongs 451: * to a subclass which declares another field to hide this one. 452: * 453: * @param o the object to set this Field on 454: * @param value the value to set this Field to 455: * @throws IllegalAccessException if you could not normally access this field 456: * (i.e. it is not public) 457: * @throws IllegalArgumentException if <code>value</code> cannot be 458: * converted by a widening conversion to the underlying type of 459: * the Field, or if <code>o</code> is not an instance of the class 460: * declaring this field 461: * @throws NullPointerException if <code>o</code> is null and this field 462: * requires an instance 463: * @throws ExceptionInInitializerError if accessing a static field triggered 464: * class initialization, which then failed 465: * @see #setBoolean(Object, boolean) 466: * @see #setByte(Object, byte) 467: * @see #setChar(Object, char) 468: * @see #setShort(Object, short) 469: * @see #setInt(Object, int) 470: * @see #setLong(Object, long) 471: * @see #setFloat(Object, float) 472: * @see #setDouble(Object, double) 473: */ 474: public native void set(Object o, Object value) 475: throws IllegalAccessException; 476: 477: /** 478: * Set this boolean Field. If the field is static, <code>o</code> will be 479: * ignored. 480: * 481: * @param o the object to set this Field on 482: * @param value the value to set this Field to 483: * @throws IllegalAccessException if you could not normally access this field 484: * (i.e. it is not public) 485: * @throws IllegalArgumentException if this is not a boolean field, or if 486: * <code>o</code> is not an instance of the class declaring this 487: * field 488: * @throws NullPointerException if <code>o</code> is null and this field 489: * requires an instance 490: * @throws ExceptionInInitializerError if accessing a static field triggered 491: * class initialization, which then failed 492: * @see #set(Object, Object) 493: */ 494: public native void setBoolean(Object o, boolean value) 495: throws IllegalAccessException; 496: 497: /** 498: * Set this byte Field. If the field is static, <code>o</code> will be 499: * ignored. 500: * 501: * @param o the object to set this Field on 502: * @param value the value to set this Field to 503: * @throws IllegalAccessException if you could not normally access this field 504: * (i.e. it is not public) 505: * @throws IllegalArgumentException if this is not a byte, short, int, long, 506: * float, or double field, or if <code>o</code> is not an instance 507: * of the class declaring this field 508: * @throws NullPointerException if <code>o</code> is null and this field 509: * requires an instance 510: * @throws ExceptionInInitializerError if accessing a static field triggered 511: * class initialization, which then failed 512: * @see #set(Object, Object) 513: */ 514: public native void setByte(Object o, byte value) 515: throws IllegalAccessException; 516: 517: /** 518: * Set this char Field. If the field is static, <code>o</code> will be 519: * ignored. 520: * 521: * @param o the object to set this Field on 522: * @param value the value to set this Field to 523: * @throws IllegalAccessException if you could not normally access this field 524: * (i.e. it is not public) 525: * @throws IllegalArgumentException if this is not a char, int, long, 526: * float, or double field, or if <code>o</code> is not an instance 527: * of the class declaring this field 528: * @throws NullPointerException if <code>o</code> is null and this field 529: * requires an instance 530: * @throws ExceptionInInitializerError if accessing a static field triggered 531: * class initialization, which then failed 532: * @see #set(Object, Object) 533: */ 534: public native void setChar(Object o, char value) 535: throws IllegalAccessException; 536: 537: /** 538: * Set this short Field. If the field is static, <code>o</code> will be 539: * ignored. 540: * 541: * @param o the object to set this Field on 542: * @param value the value to set this Field to 543: * @throws IllegalAccessException if you could not normally access this field 544: * (i.e. it is not public) 545: * @throws IllegalArgumentException if this is not a short, int, long, 546: * float, or double field, or if <code>o</code> is not an instance 547: * of the class declaring this field 548: * @throws NullPointerException if <code>o</code> is null and this field 549: * requires an instance 550: * @throws ExceptionInInitializerError if accessing a static field triggered 551: * class initialization, which then failed 552: * @see #set(Object, Object) 553: */ 554: public native void setShort(Object o, short value) 555: throws IllegalAccessException; 556: 557: /** 558: * Set this int Field. If the field is static, <code>o</code> will be 559: * ignored. 560: * 561: * @param o the object to set this Field on 562: * @param value the value to set this Field to 563: * @throws IllegalAccessException if you could not normally access this field 564: * (i.e. it is not public) 565: * @throws IllegalArgumentException if this is not an int, long, float, or 566: * double field, or if <code>o</code> is not an instance of the 567: * class declaring this field 568: * @throws NullPointerException if <code>o</code> is null and this field 569: * requires an instance 570: * @throws ExceptionInInitializerError if accessing a static field triggered 571: * class initialization, which then failed 572: * @see #set(Object, Object) 573: */ 574: public native void setInt(Object o, int value) 575: throws IllegalAccessException; 576: 577: /** 578: * Set this long Field. If the field is static, <code>o</code> will be 579: * ignored. 580: * 581: * @param o the object to set this Field on 582: * @param value the value to set this Field to 583: * @throws IllegalAccessException if you could not normally access this field 584: * (i.e. it is not public) 585: * @throws IllegalArgumentException if this is not a long, float, or double 586: * field, or if <code>o</code> is not an instance of the class 587: * declaring this field 588: * @throws NullPointerException if <code>o</code> is null and this field 589: * requires an instance 590: * @throws ExceptionInInitializerError if accessing a static field triggered 591: * class initialization, which then failed 592: * @see #set(Object, Object) 593: */ 594: public native void setLong(Object o, long value) 595: throws IllegalAccessException; 596: 597: /** 598: * Set this float Field. If the field is static, <code>o</code> will be 599: * ignored. 600: * 601: * @param o the object to set this Field on 602: * @param value the value to set this Field to 603: * @throws IllegalAccessException if you could not normally access this field 604: * (i.e. it is not public) 605: * @throws IllegalArgumentException if this is not a float or long field, or 606: * if <code>o</code> is not an instance of the class declaring this 607: * field 608: * @throws NullPointerException if <code>o</code> is null and this field 609: * requires an instance 610: * @throws ExceptionInInitializerError if accessing a static field triggered 611: * class initialization, which then failed 612: * @see #set(Object, Object) 613: */ 614: public native void setFloat(Object o, float value) 615: throws IllegalAccessException; 616: 617: /** 618: * Set this double Field. If the field is static, <code>o</code> will be 619: * ignored. 620: * 621: * @param o the object to set this Field on 622: * @param value the value to set this Field to 623: * @throws IllegalAccessException if you could not normally access this field 624: * (i.e. it is not public) 625: * @throws IllegalArgumentException if this is not a double field, or if 626: * <code>o</code> is not an instance of the class declaring this 627: * field 628: * @throws NullPointerException if <code>o</code> is null and this field 629: * requires an instance 630: * @throws ExceptionInInitializerError if accessing a static field triggered 631: * class initialization, which then failed 632: * @see #set(Object, Object) 633: */ 634: public native void setDouble(Object o, double value) 635: throws IllegalAccessException; 636: 637: /** 638: * Return the generic type of the field. If the field type is not a generic 639: * type, the method returns the same as <code>getType()</code>. 640: * 641: * @throws GenericSignatureFormatError if the generic signature does 642: * not conform to the format specified in the Virtual Machine 643: * specification, version 3. 644: * @since 1.5 645: */ 646: public Type getGenericType() 647: { 648: String signature = getSignature(); 649: if (signature == null) 650: return getType(); 651: FieldSignatureParser p = new FieldSignatureParser(getDeclaringClass(), 652: signature); 653: return p.getFieldType(); 654: } 655: 656: /** 657: * Return the String in the Signature attribute for this field. If there 658: * is no Signature attribute, return null. 659: */ 660: private native String getSignature(); 661: }
GNU Classpath (0.95) |