1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package java.lang.reflect; 28 29 import sun.reflect.CallerSensitive; 30 import sun.reflect.Reflection; 31 import java.lang.annotation.Annotation; 32 import java.util.Map; 33 import com.android.dex.Dex; 34 import libcore.reflect.GenericSignatureParser; 35 import java.util.List; 36 37 38 /** 39 * A {@code Field} provides information about, and dynamic access to, a 40 * single field of a class or an interface. The reflected field may 41 * be a class (static) field or an instance field. 42 * 43 * <p>A {@code Field} permits widening conversions to occur during a get or 44 * set access operation, but throws an {@code IllegalArgumentException} if a 45 * narrowing conversion would occur. 46 * 47 * @see Member 48 * @see java.lang.Class 49 * @see java.lang.Class#getFields() 50 * @see java.lang.Class#getField(String) 51 * @see java.lang.Class#getDeclaredFields() 52 * @see java.lang.Class#getDeclaredField(String) 53 * 54 * @author Kenneth Russell 55 * @author Nakul Saraiya 56 */ 57 public final 58 class Field extends AccessibleObject implements Member { 59 60 private int accessFlags; 61 private Class<?> declaringClass; 62 private int dexFieldIndex; 63 private int offset; 64 private Class<?> type; 65 66 private Field() { 67 } 68 69 /** 70 * Returns the {@code Class} object representing the class or interface 71 * that declares the field represented by this {@code Field} object. 72 */ 73 public Class<?> getDeclaringClass() { 74 return declaringClass; 75 } 76 77 /** 78 * Returns the name of the field represented by this {@code Field} object. 79 */ 80 public String getName() { 81 if (dexFieldIndex == -1) { 82 // Proxy classes have 1 synthesized static field with no valid dex index. 83 if (!declaringClass.isProxy()) { 84 throw new AssertionError(); 85 } 86 return "throws"; 87 } 88 Dex dex = declaringClass.getDex(); 89 int nameIndex = dex.nameIndexFromFieldIndex(dexFieldIndex); 90 return declaringClass.getDexCacheString(dex, nameIndex); 91 } 92 93 /** 94 * Returns the Java language modifiers for the field represented 95 * by this {@code Field} object, as an integer. The {@code Modifier} class should 96 * be used to decode the modifiers. 97 * 98 * @see Modifier 99 */ 100 public int getModifiers() { 101 return accessFlags & 0xffff; // mask out bits not used by Java 102 } 103 104 /** 105 * Returns {@code true} if this field represents an element of 106 * an enumerated type; returns {@code false} otherwise. 107 * 108 * @return {@code true} if and only if this field represents an element of 109 * an enumerated type. 110 * @since 1.5 111 */ 112 public boolean isEnumConstant() { 113 return (getModifiers() & Modifier.ENUM) != 0; 114 } 115 116 /** 117 * Returns {@code true} if this field is a synthetic 118 * field; returns {@code false} otherwise. 119 * 120 * @return true if and only if this field is a synthetic 121 * field as defined by the Java Language Specification. 122 * @since 1.5 123 */ 124 public boolean isSynthetic() { 125 return Modifier.isSynthetic(getModifiers()); 126 } 127 128 /** 129 * Returns a {@code Class} object that identifies the 130 * declared type for the field represented by this 131 * {@code Field} object. 132 * 133 * @return a {@code Class} object identifying the declared 134 * type of the field represented by this object 135 */ 136 public Class<?> getType() { 137 return type; 138 } 139 140 /** 141 * Returns a {@code Type} object that represents the declared type for 142 * the field represented by this {@code Field} object. 143 * 144 * <p>If the {@code Type} is a parameterized type, the 145 * {@code Type} object returned must accurately reflect the 146 * actual type parameters used in the source code. 147 * 148 * <p>If the type of the underlying field is a type variable or a 149 * parameterized type, it is created. Otherwise, it is resolved. 150 * 151 * @return a {@code Type} object that represents the declared type for 152 * the field represented by this {@code Field} object 153 * @throws GenericSignatureFormatError if the generic field 154 * signature does not conform to the format specified in 155 * <cite>The Java™ Virtual Machine Specification</cite> 156 * @throws TypeNotPresentException if the generic type 157 * signature of the underlying field refers to a non-existent 158 * type declaration 159 * @throws MalformedParameterizedTypeException if the generic 160 * signature of the underlying field refers to a parameterized type 161 * that cannot be instantiated for any reason 162 * @since 1.5 163 */ 164 public Type getGenericType() { 165 String signatureAttribute = getSignatureAttribute(); 166 ClassLoader cl = declaringClass.getClassLoader(); 167 GenericSignatureParser parser = new GenericSignatureParser(cl); 168 parser.parseForField(declaringClass, signatureAttribute); 169 Type genericType = parser.fieldType; 170 if (genericType == null) { 171 genericType = getType(); 172 } 173 return genericType; 174 } 175 176 private String getSignatureAttribute() { 177 String[] annotation = getSignatureAnnotation(); 178 if (annotation == null) { 179 return null; 180 } 181 StringBuilder result = new StringBuilder(); 182 for (String s : annotation) { 183 result.append(s); 184 } 185 return result.toString(); 186 } 187 private native String[] getSignatureAnnotation(); 188 189 190 /** 191 * Compares this {@code Field} against the specified object. Returns 192 * true if the objects are the same. Two {@code Field} objects are the same if 193 * they were declared by the same class and have the same name 194 * and type. 195 */ 196 public boolean equals(Object obj) { 197 if (obj != null && obj instanceof Field) { 198 Field other = (Field)obj; 199 return (getDeclaringClass() == other.getDeclaringClass()) 200 && (getName() == other.getName()) 201 && (getType() == other.getType()); 202 } 203 return false; 204 } 205 206 /** 207 * Returns a hashcode for this {@code Field}. This is computed as the 208 * exclusive-or of the hashcodes for the underlying field's 209 * declaring class name and its name. 210 */ 211 public int hashCode() { 212 return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); 213 } 214 215 /** 216 * Returns a string describing this {@code Field}. The format is 217 * the access modifiers for the field, if any, followed 218 * by the field type, followed by a space, followed by 219 * the fully-qualified name of the class declaring the field, 220 * followed by a period, followed by the name of the field. 221 * For example: 222 * <pre> 223 * public static final int java.lang.Thread.MIN_PRIORITY 224 * private int java.io.FileDescriptor.fd 225 * </pre> 226 * 227 * <p>The modifiers are placed in canonical order as specified by 228 * "The Java Language Specification". This is {@code public}, 229 * {@code protected} or {@code private} first, and then other 230 * modifiers in the following order: {@code static}, {@code final}, 231 * {@code transient}, {@code volatile}. 232 */ 233 public String toString() { 234 int mod = getModifiers(); 235 return (((mod == 0) ? "" : (Modifier.toString(mod) + " ")) 236 + getTypeName(getType()) + " " 237 + getTypeName(getDeclaringClass()) + "." 238 + getName()); 239 } 240 241 /** 242 * Returns a string describing this {@code Field}, including 243 * its generic type. The format is the access modifiers for the 244 * field, if any, followed by the generic field type, followed by 245 * a space, followed by the fully-qualified name of the class 246 * declaring the field, followed by a period, followed by the name 247 * of the field. 248 * 249 * <p>The modifiers are placed in canonical order as specified by 250 * "The Java Language Specification". This is {@code public}, 251 * {@code protected} or {@code private} first, and then other 252 * modifiers in the following order: {@code static}, {@code final}, 253 * {@code transient}, {@code volatile}. 254 * 255 * @return a string describing this {@code Field}, including 256 * its generic type 257 * 258 * @since 1.5 259 */ 260 public String toGenericString() { 261 int mod = getModifiers(); 262 Type fieldType = getGenericType(); 263 return (((mod == 0) ? "" : (Modifier.toString(mod) + " ")) 264 + ((fieldType instanceof Class) ? 265 getTypeName((Class)fieldType): fieldType.toString())+ " " 266 + getTypeName(getDeclaringClass()) + "." 267 + getName()); 268 } 269 270 /** 271 * Returns the value of the field represented by this {@code Field}, on 272 * the specified object. The value is automatically wrapped in an 273 * object if it has a primitive type. 274 * 275 * <p>The underlying field's value is obtained as follows: 276 * 277 * <p>If the underlying field is a static field, the {@code obj} argument 278 * is ignored; it may be null. 279 * 280 * <p>Otherwise, the underlying field is an instance field. If the 281 * specified {@code obj} argument is null, the method throws a 282 * {@code NullPointerException}. If the specified object is not an 283 * instance of the class or interface declaring the underlying 284 * field, the method throws an {@code IllegalArgumentException}. 285 * 286 * <p>If this {@code Field} object is enforcing Java language access control, and 287 * the underlying field is inaccessible, the method throws an 288 * {@code IllegalAccessException}. 289 * If the underlying field is static, the class that declared the 290 * field is initialized if it has not already been initialized. 291 * 292 * <p>Otherwise, the value is retrieved from the underlying instance 293 * or static field. If the field has a primitive type, the value 294 * is wrapped in an object before being returned, otherwise it is 295 * returned as is. 296 * 297 * <p>If the field is hidden in the type of {@code obj}, 298 * the field's value is obtained according to the preceding rules. 299 * 300 * @param object object from which the represented field's value is 301 * to be extracted 302 * @return the value of the represented field in object 303 * {@code obj}; primitive values are wrapped in an appropriate 304 * object before being returned 305 * 306 * @exception IllegalAccessException if this {@code Field} object 307 * is enforcing Java language access control and the underlying 308 * field is inaccessible. 309 * @exception IllegalArgumentException if the specified object is not an 310 * instance of the class or interface declaring the underlying 311 * field (or a subclass or implementor thereof). 312 * @exception NullPointerException if the specified object is null 313 * and the field is an instance field. 314 * @exception ExceptionInInitializerError if the initialization provoked 315 * by this method fails. 316 */ 317 public native Object get(Object object) 318 throws IllegalAccessException, IllegalArgumentException; 319 320 /** 321 * Gets the value of a static or instance {@code boolean} field. 322 * 323 * @param object the object to extract the {@code boolean} value 324 * from 325 * @return the value of the {@code boolean} field 326 * 327 * @exception IllegalAccessException if this {@code Field} object 328 * is enforcing Java language access control and the underlying 329 * field is inaccessible. 330 * @exception IllegalArgumentException if the specified object is not 331 * an instance of the class or interface declaring the 332 * underlying field (or a subclass or implementor 333 * thereof), or if the field value cannot be 334 * converted to the type {@code boolean} by a 335 * widening conversion. 336 * @exception NullPointerException if the specified object is null 337 * and the field is an instance field. 338 * @exception ExceptionInInitializerError if the initialization provoked 339 * by this method fails. 340 * @see Field#get 341 */ 342 public native boolean getBoolean(Object object) 343 throws IllegalAccessException, IllegalArgumentException; 344 345 /** 346 * Gets the value of a static or instance {@code byte} field. 347 * 348 * @param object the object to extract the {@code byte} value 349 * from 350 * @return the value of the {@code byte} field 351 * 352 * @exception IllegalAccessException if this {@code Field} object 353 * is enforcing Java language access control and the underlying 354 * field is inaccessible. 355 * @exception IllegalArgumentException if the specified object is not 356 * an instance of the class or interface declaring the 357 * underlying field (or a subclass or implementor 358 * thereof), or if the field value cannot be 359 * converted to the type {@code byte} by a 360 * widening conversion. 361 * @exception NullPointerException if the specified object is null 362 * and the field is an instance field. 363 * @exception ExceptionInInitializerError if the initialization provoked 364 * by this method fails. 365 * @see Field#get 366 */ 367 public native byte getByte(Object object) 368 throws IllegalAccessException, IllegalArgumentException; 369 370 /** 371 * Gets the value of a static or instance field of type 372 * {@code char} or of another primitive type convertible to 373 * type {@code char} via a widening conversion. 374 * 375 * @param object the object to extract the {@code char} value 376 * from 377 * @return the value of the field converted to type {@code char} 378 * 379 * @exception IllegalAccessException if this {@code Field} object 380 * is enforcing Java language access control and the underlying 381 * field is inaccessible. 382 * @exception IllegalArgumentException if the specified object is not 383 * an instance of the class or interface declaring the 384 * underlying field (or a subclass or implementor 385 * thereof), or if the field value cannot be 386 * converted to the type {@code char} by a 387 * widening conversion. 388 * @exception NullPointerException if the specified object is null 389 * and the field is an instance field. 390 * @exception ExceptionInInitializerError if the initialization provoked 391 * by this method fails. 392 * @see Field#get 393 */ 394 public native char getChar(Object object) 395 throws IllegalAccessException, IllegalArgumentException; 396 397 /** 398 * Gets the value of a static or instance field of type 399 * {@code short} or of another primitive type convertible to 400 * type {@code short} via a widening conversion. 401 * 402 * @param object the object to extract the {@code short} value 403 * from 404 * @return the value of the field converted to type {@code short} 405 * 406 * @exception IllegalAccessException if this {@code Field} object 407 * is enforcing Java language access control and the underlying 408 * field is inaccessible. 409 * @exception IllegalArgumentException if the specified object is not 410 * an instance of the class or interface declaring the 411 * underlying field (or a subclass or implementor 412 * thereof), or if the field value cannot be 413 * converted to the type {@code short} by a 414 * widening conversion. 415 * @exception NullPointerException if the specified object is null 416 * and the field is an instance field. 417 * @exception ExceptionInInitializerError if the initialization provoked 418 * by this method fails. 419 * @see Field#get 420 */ 421 public native short getShort(Object object) 422 throws IllegalAccessException, IllegalArgumentException; 423 424 /** 425 * Gets the value of a static or instance field of type 426 * {@code int} or of another primitive type convertible to 427 * type {@code int} via a widening conversion. 428 * 429 * @param object the object to extract the {@code int} value 430 * from 431 * @return the value of the field converted to type {@code int} 432 * 433 * @exception IllegalAccessException if this {@code Field} object 434 * is enforcing Java language access control and the underlying 435 * field is inaccessible. 436 * @exception IllegalArgumentException if the specified object is not 437 * an instance of the class or interface declaring the 438 * underlying field (or a subclass or implementor 439 * thereof), or if the field value cannot be 440 * converted to the type {@code int} by a 441 * widening conversion. 442 * @exception NullPointerException if the specified object is null 443 * and the field is an instance field. 444 * @exception ExceptionInInitializerError if the initialization provoked 445 * by this method fails. 446 * @see Field#get 447 */ 448 public native int getInt(Object object) 449 throws IllegalAccessException, IllegalArgumentException; 450 451 /** 452 * Gets the value of a static or instance field of type 453 * {@code long} or of another primitive type convertible to 454 * type {@code long} via a widening conversion. 455 * 456 * @param object the object to extract the {@code long} value 457 * from 458 * @return the value of the field converted to type {@code long} 459 * 460 * @exception IllegalAccessException if this {@code Field} object 461 * is enforcing Java language access control and the underlying 462 * field is inaccessible. 463 * @exception IllegalArgumentException if the specified object is not 464 * an instance of the class or interface declaring the 465 * underlying field (or a subclass or implementor 466 * thereof), or if the field value cannot be 467 * converted to the type {@code long} by a 468 * widening conversion. 469 * @exception NullPointerException if the specified object is null 470 * and the field is an instance field. 471 * @exception ExceptionInInitializerError if the initialization provoked 472 * by this method fails. 473 * @see Field#get 474 */ 475 public native long getLong(Object object) 476 throws IllegalAccessException, IllegalArgumentException; 477 478 /** 479 * Gets the value of a static or instance field of type 480 * {@code float} or of another primitive type convertible to 481 * type {@code float} via a widening conversion. 482 * 483 * @param object the object to extract the {@code float} value 484 * from 485 * @return the value of the field converted to type {@code float} 486 * 487 * @exception IllegalAccessException if this {@code Field} object 488 * is enforcing Java language access control and the underlying 489 * field is inaccessible. 490 * @exception IllegalArgumentException if the specified object is not 491 * an instance of the class or interface declaring the 492 * underlying field (or a subclass or implementor 493 * thereof), or if the field value cannot be 494 * converted to the type {@code float} by a 495 * widening conversion. 496 * @exception NullPointerException if the specified object is null 497 * and the field is an instance field. 498 * @exception ExceptionInInitializerError if the initialization provoked 499 * by this method fails. 500 * @see Field#get 501 */ 502 public native float getFloat(Object object) 503 throws IllegalAccessException, IllegalArgumentException; 504 505 /** 506 * Gets the value of a static or instance field of type 507 * {@code double} or of another primitive type convertible to 508 * type {@code double} via a widening conversion. 509 * 510 * @param object the object to extract the {@code double} value 511 * from 512 * @return the value of the field converted to type {@code double} 513 * 514 * @exception IllegalAccessException if this {@code Field} object 515 * is enforcing Java language access control and the underlying 516 * field is inaccessible. 517 * @exception IllegalArgumentException if the specified object is not 518 * an instance of the class or interface declaring the 519 * underlying field (or a subclass or implementor 520 * thereof), or if the field value cannot be 521 * converted to the type {@code double} by a 522 * widening conversion. 523 * @exception NullPointerException if the specified object is null 524 * and the field is an instance field. 525 * @exception ExceptionInInitializerError if the initialization provoked 526 * by this method fails. 527 * @see Field#get 528 */ 529 public native double getDouble(Object object) 530 throws IllegalAccessException, IllegalArgumentException; 531 532 /** 533 * Sets the field represented by this {@code Field} object on the 534 * specified object argument to the specified new value. The new 535 * value is automatically unwrapped if the underlying field has a 536 * primitive type. 537 * 538 * <p>The operation proceeds as follows: 539 * 540 * <p>If the underlying field is static, the {@code obj} argument is 541 * ignored; it may be null. 542 * 543 * <p>Otherwise the underlying field is an instance field. If the 544 * specified object argument is null, the method throws a 545 * {@code NullPointerException}. If the specified object argument is not 546 * an instance of the class or interface declaring the underlying 547 * field, the method throws an {@code IllegalArgumentException}. 548 * 549 * <p>If this {@code Field} object is enforcing Java language access control, and 550 * the underlying field is inaccessible, the method throws an 551 * {@code IllegalAccessException}. 552 * 553 * <p>If the underlying field is final, the method throws an 554 * {@code IllegalAccessException} unless {@code setAccessible(true)} 555 * has succeeded for this {@code Field} object 556 * and the field is non-static. Setting a final field in this way 557 * is meaningful only during deserialization or reconstruction of 558 * instances of classes with blank final fields, before they are 559 * made available for access by other parts of a program. Use in 560 * any other context may have unpredictable effects, including cases 561 * in which other parts of a program continue to use the original 562 * value of this field. 563 * 564 * <p>If the underlying field is of a primitive type, an unwrapping 565 * conversion is attempted to convert the new value to a value of 566 * a primitive type. If this attempt fails, the method throws an 567 * {@code IllegalArgumentException}. 568 * 569 * <p>If, after possible unwrapping, the new value cannot be 570 * converted to the type of the underlying field by an identity or 571 * widening conversion, the method throws an 572 * {@code IllegalArgumentException}. 573 * 574 * <p>If the underlying field is static, the class that declared the 575 * field is initialized if it has not already been initialized. 576 * 577 * <p>The field is set to the possibly unwrapped and widened new value. 578 * 579 * <p>If the field is hidden in the type of {@code obj}, 580 * the field's value is set according to the preceding rules. 581 * 582 * @param object the object whose field should be modified 583 * @param value the new value for the field of {@code obj} 584 * being modified 585 * 586 * @exception IllegalAccessException if this {@code Field} object 587 * is enforcing Java language access control and the underlying 588 * field is either inaccessible or final. 589 * @exception IllegalArgumentException if the specified object is not an 590 * instance of the class or interface declaring the underlying 591 * field (or a subclass or implementor thereof), 592 * or if an unwrapping conversion fails. 593 * @exception NullPointerException if the specified object is null 594 * and the field is an instance field. 595 * @exception ExceptionInInitializerError if the initialization provoked 596 * by this method fails. 597 */ 598 public native void set(Object object, Object value) 599 throws IllegalAccessException, IllegalArgumentException; 600 601 /** 602 * Sets the value of a field as a {@code boolean} on the specified object. 603 * This method is equivalent to 604 * {@code set(obj, zObj)}, 605 * where {@code zObj} is a {@code Boolean} object and 606 * {@code zObj.booleanValue() == z}. 607 * 608 * @param object the object whose field should be modified 609 * @param value the new value for the field of {@code obj} 610 * being modified 611 * 612 * @exception IllegalAccessException if this {@code Field} object 613 * is enforcing Java language access control and the underlying 614 * field is either inaccessible or final. 615 * @exception IllegalArgumentException if the specified object is not an 616 * instance of the class or interface declaring the underlying 617 * field (or a subclass or implementor thereof), 618 * or if an unwrapping conversion fails. 619 * @exception NullPointerException if the specified object is null 620 * and the field is an instance field. 621 * @exception ExceptionInInitializerError if the initialization provoked 622 * by this method fails. 623 * @see Field#set 624 */ 625 public native void setBoolean(Object object, boolean value) 626 throws IllegalAccessException, IllegalArgumentException; 627 628 /** 629 * Sets the value of a field as a {@code byte} on the specified object. 630 * This method is equivalent to 631 * {@code set(obj, bObj)}, 632 * where {@code bObj} is a {@code Byte} object and 633 * {@code bObj.byteValue() == b}. 634 * 635 * @param object the object whose field should be modified 636 * @param value the new value for the field of {@code obj} 637 * being modified 638 * 639 * @exception IllegalAccessException if this {@code Field} object 640 * is enforcing Java language access control and the underlying 641 * field is either inaccessible or final. 642 * @exception IllegalArgumentException if the specified object is not an 643 * instance of the class or interface declaring the underlying 644 * field (or a subclass or implementor thereof), 645 * or if an unwrapping conversion fails. 646 * @exception NullPointerException if the specified object is null 647 * and the field is an instance field. 648 * @exception ExceptionInInitializerError if the initialization provoked 649 * by this method fails. 650 * @see Field#set 651 */ 652 public native void setByte(Object object, byte value) 653 throws IllegalAccessException, IllegalArgumentException; 654 655 /** 656 * Sets the value of a field as a {@code char} on the specified object. 657 * This method is equivalent to 658 * {@code set(obj, cObj)}, 659 * where {@code cObj} is a {@code Character} object and 660 * {@code cObj.charValue() == c}. 661 * 662 * @param object the object whose field should be modified 663 * @param value the new value for the field of {@code obj} 664 * being modified 665 * 666 * @exception IllegalAccessException if this {@code Field} object 667 * is enforcing Java language access control and the underlying 668 * field is either inaccessible or final. 669 * @exception IllegalArgumentException if the specified object is not an 670 * instance of the class or interface declaring the underlying 671 * field (or a subclass or implementor thereof), 672 * or if an unwrapping conversion fails. 673 * @exception NullPointerException if the specified object is null 674 * and the field is an instance field. 675 * @exception ExceptionInInitializerError if the initialization provoked 676 * by this method fails. 677 * @see Field#set 678 */ 679 public native void setChar(Object object, char value) 680 throws IllegalAccessException, IllegalArgumentException; 681 682 /** 683 * Sets the value of a field as a {@code short} on the specified object. 684 * This method is equivalent to 685 * {@code set(obj, sObj)}, 686 * where {@code sObj} is a {@code Short} object and 687 * {@code sObj.shortValue() == s}. 688 * 689 * @param object the object whose field should be modified 690 * @param value the new value for the field of {@code obj} 691 * being modified 692 * 693 * @exception IllegalAccessException if this {@code Field} object 694 * is enforcing Java language access control and the underlying 695 * field is either inaccessible or final. 696 * @exception IllegalArgumentException if the specified object is not an 697 * instance of the class or interface declaring the underlying 698 * field (or a subclass or implementor thereof), 699 * or if an unwrapping conversion fails. 700 * @exception NullPointerException if the specified object is null 701 * and the field is an instance field. 702 * @exception ExceptionInInitializerError if the initialization provoked 703 * by this method fails. 704 * @see Field#set 705 */ 706 public native void setShort(Object object, short value) 707 throws IllegalAccessException, IllegalArgumentException; 708 709 /** 710 * Sets the value of a field as an {@code int} on the specified object. 711 * This method is equivalent to 712 * {@code set(obj, iObj)}, 713 * where {@code iObj} is a {@code Integer} object and 714 * {@code iObj.intValue() == i}. 715 * 716 * @param object the object whose field should be modified 717 * @param value the new value for the field of {@code obj} 718 * being modified 719 * 720 * @exception IllegalAccessException if this {@code Field} object 721 * is enforcing Java language access control and the underlying 722 * field is either inaccessible or final. 723 * @exception IllegalArgumentException if the specified object is not an 724 * instance of the class or interface declaring the underlying 725 * field (or a subclass or implementor thereof), 726 * or if an unwrapping conversion fails. 727 * @exception NullPointerException if the specified object is null 728 * and the field is an instance field. 729 * @exception ExceptionInInitializerError if the initialization provoked 730 * by this method fails. 731 * @see Field#set 732 */ 733 public native void setInt(Object object, int value) 734 throws IllegalAccessException, IllegalArgumentException; 735 736 /** 737 * Sets the value of a field as a {@code long} on the specified object. 738 * This method is equivalent to 739 * {@code set(obj, lObj)}, 740 * where {@code lObj} is a {@code Long} object and 741 * {@code lObj.longValue() == l}. 742 * 743 * @param object the object whose field should be modified 744 * @param value the new value for the field of {@code obj} 745 * being modified 746 * 747 * @exception IllegalAccessException if this {@code Field} object 748 * is enforcing Java language access control and the underlying 749 * field is either inaccessible or final. 750 * @exception IllegalArgumentException if the specified object is not an 751 * instance of the class or interface declaring the underlying 752 * field (or a subclass or implementor thereof), 753 * or if an unwrapping conversion fails. 754 * @exception NullPointerException if the specified object is null 755 * and the field is an instance field. 756 * @exception ExceptionInInitializerError if the initialization provoked 757 * by this method fails. 758 * @see Field#set 759 */ 760 public native void setLong(Object object, long value) 761 throws IllegalAccessException, IllegalArgumentException; 762 763 /** 764 * Sets the value of a field as a {@code float} on the specified object. 765 * This method is equivalent to 766 * {@code set(obj, fObj)}, 767 * where {@code fObj} is a {@code Float} object and 768 * {@code fObj.floatValue() == f}. 769 * 770 * @param object the object whose field should be modified 771 * @param value the new value for the field of {@code obj} 772 * being modified 773 * 774 * @exception IllegalAccessException if this {@code Field} object 775 * is enforcing Java language access control and the underlying 776 * field is either inaccessible or final. 777 * @exception IllegalArgumentException if the specified object is not an 778 * instance of the class or interface declaring the underlying 779 * field (or a subclass or implementor thereof), 780 * or if an unwrapping conversion fails. 781 * @exception NullPointerException if the specified object is null 782 * and the field is an instance field. 783 * @exception ExceptionInInitializerError if the initialization provoked 784 * by this method fails. 785 * @see Field#set 786 */ 787 public native void setFloat(Object object, float value) 788 throws IllegalAccessException, IllegalArgumentException; 789 790 /** 791 * Sets the value of a field as a {@code double} on the specified object. 792 * This method is equivalent to 793 * {@code set(obj, dObj)}, 794 * where {@code dObj} is a {@code Double} object and 795 * {@code dObj.doubleValue() == d}. 796 * 797 * @param object the object whose field should be modified 798 * @param value the new value for the field of {@code obj} 799 * being modified 800 * 801 * @exception IllegalAccessException if this {@code Field} object 802 * is enforcing Java language access control and the underlying 803 * field is either inaccessible or final. 804 * @exception IllegalArgumentException if the specified object is not an 805 * instance of the class or interface declaring the underlying 806 * field (or a subclass or implementor thereof), 807 * or if an unwrapping conversion fails. 808 * @exception NullPointerException if the specified object is null 809 * and the field is an instance field. 810 * @exception ExceptionInInitializerError if the initialization provoked 811 * by this method fails. 812 * @see Field#set 813 */ 814 public native void setDouble(Object object, double value) 815 throws IllegalAccessException, IllegalArgumentException; 816 817 /* 818 * Utility routine to paper over array type names 819 */ 820 static String getTypeName(Class<?> type) { 821 if (type.isArray()) { 822 try { 823 Class<?> cl = type; 824 int dimensions = 0; 825 while (cl.isArray()) { 826 dimensions++; 827 cl = cl.getComponentType(); 828 } 829 StringBuffer sb = new StringBuffer(); 830 sb.append(cl.getName()); 831 for (int i = 0; i < dimensions; i++) { 832 sb.append("[]"); 833 } 834 return sb.toString(); 835 } catch (Throwable e) { /*FALLTHRU*/ } 836 } 837 return type.getName(); 838 } 839 840 /** 841 * @throws NullPointerException {@inheritDoc} 842 * @since 1.5 843 */ 844 @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) { 845 if (annotationType == null) { 846 throw new NullPointerException("annotationType == null"); 847 } 848 return getAnnotationNative(annotationType); 849 } 850 private native <A extends Annotation> A getAnnotationNative(Class<A> annotationType); 851 852 @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) { 853 if (annotationType == null) { 854 throw new NullPointerException("annotationType == null"); 855 } 856 return isAnnotationPresentNative(annotationType); 857 } 858 private native boolean isAnnotationPresentNative(Class<? extends Annotation> annotationType); 859 860 /** 861 * @since 1.5 862 */ 863 @Override public native Annotation[] getDeclaredAnnotations(); 864 865 /** 866 * Returns the index of this field's ID in its dex file. 867 * 868 * @hide 869 */ 870 public int getDexFieldIndex() { 871 return dexFieldIndex; 872 } 873 874 /** 875 * Returns the offset of the field within an instance, or for static fields, the class. 876 * 877 * @hide 878 */ 879 public int getOffset() { 880 return offset; 881 } 882 } 883