1 /* 2 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.lang.reflect; 27 28 import sun.reflect.FieldAccessor; 29 import sun.reflect.Reflection; 30 import sun.reflect.generics.repository.FieldRepository; 31 import sun.reflect.generics.factory.CoreReflectionFactory; 32 import sun.reflect.generics.factory.GenericsFactory; 33 import sun.reflect.generics.scope.ClassScope; 34 import java.lang.annotation.Annotation; 35 import java.util.Map; 36 import java.util.Objects; 37 import sun.reflect.annotation.AnnotationParser; 38 import sun.reflect.annotation.AnnotationSupport; 39 import sun.reflect.annotation.TypeAnnotation; 40 import sun.reflect.annotation.TypeAnnotationParser; 41 42 /** 43 * A {@code Field} provides information about, and dynamic access to, a 44 * single field of a class or an interface. The reflected field may 45 * be a class (static) field or an instance field. 46 * 47 * <p>A {@code Field} permits widening conversions to occur during a get or 48 * set access operation, but throws an {@code IllegalArgumentException} if a 49 * narrowing conversion would occur. 50 * 51 * @see Member 52 * @see java.lang.Class 53 * @see java.lang.Class#getFields() 54 * @see java.lang.Class#getField(String) 55 * @see java.lang.Class#getDeclaredFields() 56 * @see java.lang.Class#getDeclaredField(String) 57 * 58 * @author Kenneth Russell 59 * @author Nakul Saraiya 60 */ 61 public final 62 class Field extends AccessibleObject implements Member { 63 64 private Class<?> clazz; 65 private int slot; 66 // This is guaranteed to be interned by the VM in the 1.4 67 // reflection implementation 68 private String name; 69 private Class<?> type; 70 private int modifiers; 71 // Generics and annotations support 72 private transient String signature; 73 // generic info repository; lazily initialized 74 private transient FieldRepository genericInfo; 75 private byte[] annotations; 76 // Cached field accessor created without override 77 private FieldAccessor fieldAccessor; 78 // Cached field accessor created with override 79 private FieldAccessor overrideFieldAccessor; 80 // For sharing of FieldAccessors. This branching structure is 81 // currently only two levels deep (i.e., one root Field and 82 // potentially many Field objects pointing to it.) 83 private Field root; 84 // This is set by the vm at Field creation 85 private byte[] typeAnnotations; 86 87 // Generics infrastructure 88 89 private String getGenericSignature() {return signature;} 90 91 // Accessor for factory 92 private GenericsFactory getFactory() { 93 Class<?> c = getDeclaringClass(); 94 // create scope and factory 95 return CoreReflectionFactory.make(c, ClassScope.make(c)); 96 } 97 98 // Accessor for generic info repository 99 private FieldRepository getGenericInfo() { 100 // lazily initialize repository if necessary 101 if (genericInfo == null) { 102 // create and cache generic info repository 103 genericInfo = FieldRepository.make(getGenericSignature(), 104 getFactory()); 105 } 106 return genericInfo; //return cached repository 107 } 108 109 110 /** 111 * Package-private constructor used by ReflectAccess to enable 112 * instantiation of these objects in Java code from the java.lang 113 * package via sun.reflect.LangReflectAccess. 114 */ 115 Field(Class<?> declaringClass, 116 String name, 117 Class<?> type, 118 int modifiers, 119 int slot, 120 String signature, 121 byte[] annotations) 122 { 123 this.clazz = declaringClass; 124 this.name = name; 125 this.type = type; 126 this.modifiers = modifiers; 127 this.slot = slot; 128 this.signature = signature; 129 this.annotations = annotations; 130 } 131 132 /** 133 * Package-private routine (exposed to java.lang.Class via 134 * ReflectAccess) which returns a copy of this Field. The copy's 135 * "root" field points to this Field. 136 */ 137 Field copy() { 138 // This routine enables sharing of FieldAccessor objects 139 // among Field objects which refer to the same underlying 140 // method in the VM. (All of this contortion is only necessary 141 // because of the "accessibility" bit in AccessibleObject, 142 // which implicitly requires that new java.lang.reflect 143 // objects be fabricated for each reflective call on Class 144 // objects.) 145 Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations); 146 res.root = this; 147 // Might as well eagerly propagate this if already present 148 res.fieldAccessor = fieldAccessor; 149 res.overrideFieldAccessor = overrideFieldAccessor; 150 151 res.typeAnnotations = typeAnnotations; 152 return res; 153 } 154 155 /** 156 * Returns the {@code Class} object representing the class or interface 157 * that declares the field represented by this {@code Field} object. 158 */ 159 public Class<?> getDeclaringClass() { 160 return clazz; 161 } 162 163 /** 164 * Returns the name of the field represented by this {@code Field} object. 165 */ 166 public String getName() { 167 return name; 168 } 169 170 /** 171 * Returns the Java language modifiers for the field represented 172 * by this {@code Field} object, as an integer. The {@code Modifier} class should 173 * be used to decode the modifiers. 174 * 175 * @see Modifier 176 */ 177 public int getModifiers() { 178 return modifiers; 179 } 180 181 /** 182 * Returns {@code true} if this field represents an element of 183 * an enumerated type; returns {@code false} otherwise. 184 * 185 * @return {@code true} if and only if this field represents an element of 186 * an enumerated type. 187 * @since 1.5 188 */ 189 public boolean isEnumConstant() { 190 return (getModifiers() & Modifier.ENUM) != 0; 191 } 192 193 /** 194 * Returns {@code true} if this field is a synthetic 195 * field; returns {@code false} otherwise. 196 * 197 * @return true if and only if this field is a synthetic 198 * field as defined by the Java Language Specification. 199 * @since 1.5 200 */ 201 public boolean isSynthetic() { 202 return Modifier.isSynthetic(getModifiers()); 203 } 204 205 /** 206 * Returns a {@code Class} object that identifies the 207 * declared type for the field represented by this 208 * {@code Field} object. 209 * 210 * @return a {@code Class} object identifying the declared 211 * type of the field represented by this object 212 */ 213 public Class<?> getType() { 214 return type; 215 } 216 217 /** 218 * Returns a {@code Type} object that represents the declared type for 219 * the field represented by this {@code Field} object. 220 * 221 * <p>If the {@code Type} is a parameterized type, the 222 * {@code Type} object returned must accurately reflect the 223 * actual type parameters used in the source code. 224 * 225 * <p>If the type of the underlying field is a type variable or a 226 * parameterized type, it is created. Otherwise, it is resolved. 227 * 228 * @return a {@code Type} object that represents the declared type for 229 * the field represented by this {@code Field} object 230 * @throws GenericSignatureFormatError if the generic field 231 * signature does not conform to the format specified in 232 * <cite>The Java™ Virtual Machine Specification</cite> 233 * @throws TypeNotPresentException if the generic type 234 * signature of the underlying field refers to a non-existent 235 * type declaration 236 * @throws MalformedParameterizedTypeException if the generic 237 * signature of the underlying field refers to a parameterized type 238 * that cannot be instantiated for any reason 239 * @since 1.5 240 */ 241 public Type getGenericType() { 242 if (getGenericSignature() != null) 243 return getGenericInfo().getGenericType(); 244 else 245 return getType(); 246 } 247 248 249 /** 250 * Compares this {@code Field} against the specified object. Returns 251 * true if the objects are the same. Two {@code Field} objects are the same if 252 * they were declared by the same class and have the same name 253 * and type. 254 */ 255 public boolean equals(Object obj) { 256 if (obj != null && obj instanceof Field) { 257 Field other = (Field)obj; 258 return (getDeclaringClass() == other.getDeclaringClass()) 259 && (getName() == other.getName()) 260 && (getType() == other.getType()); 261 } 262 return false; 263 } 264 265 /** 266 * Returns a hashcode for this {@code Field}. This is computed as the 267 * exclusive-or of the hashcodes for the underlying field's 268 * declaring class name and its name. 269 */ 270 public int hashCode() { 271 return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); 272 } 273 274 /** 275 * Returns a string describing this {@code Field}. The format is 276 * the access modifiers for the field, if any, followed 277 * by the field type, followed by a space, followed by 278 * the fully-qualified name of the class declaring the field, 279 * followed by a period, followed by the name of the field. 280 * For example: 281 * <pre> 282 * public static final int java.lang.Thread.MIN_PRIORITY 283 * private int java.io.FileDescriptor.fd 284 * </pre> 285 * 286 * <p>The modifiers are placed in canonical order as specified by 287 * "The Java Language Specification". This is {@code public}, 288 * {@code protected} or {@code private} first, and then other 289 * modifiers in the following order: {@code static}, {@code final}, 290 * {@code transient}, {@code volatile}. 291 * 292 * @return a string describing this {@code Field} 293 * @jls 8.3.1 Field Modifiers 294 */ 295 public String toString() { 296 int mod = getModifiers(); 297 return (((mod == 0) ? "" : (Modifier.toString(mod) + " ")) 298 + getTypeName(getType()) + " " 299 + getTypeName(getDeclaringClass()) + "." 300 + getName()); 301 } 302 303 /** 304 * Returns a string describing this {@code Field}, including 305 * its generic type. The format is the access modifiers for the 306 * field, if any, followed by the generic field type, followed by 307 * a space, followed by the fully-qualified name of the class 308 * declaring the field, followed by a period, followed by the name 309 * of the field. 310 * 311 * <p>The modifiers are placed in canonical order as specified by 312 * "The Java Language Specification". This is {@code public}, 313 * {@code protected} or {@code private} first, and then other 314 * modifiers in the following order: {@code static}, {@code final}, 315 * {@code transient}, {@code volatile}. 316 * 317 * @return a string describing this {@code Field}, including 318 * its generic type 319 * 320 * @since 1.5 321 * @jls 8.3.1 Field Modifiers 322 */ 323 public String toGenericString() { 324 int mod = getModifiers(); 325 Type fieldType = getGenericType(); 326 return (((mod == 0) ? "" : (Modifier.toString(mod) + " ")) 327 + ((fieldType instanceof Class) ? 328 getTypeName((Class)fieldType): fieldType.toString())+ " " 329 + getTypeName(getDeclaringClass()) + "." 330 + getName()); 331 } 332 333 /** 334 * Returns the value of the field represented by this {@code Field}, on 335 * the specified object. The value is automatically wrapped in an 336 * object if it has a primitive type. 337 * 338 * <p>The underlying field's value is obtained as follows: 339 * 340 * <p>If the underlying field is a static field, the {@code obj} argument 341 * is ignored; it may be null. 342 * 343 * <p>Otherwise, the underlying field is an instance field. If the 344 * specified {@code obj} argument is null, the method throws a 345 * {@code NullPointerException}. If the specified object is not an 346 * instance of the class or interface declaring the underlying 347 * field, the method throws an {@code IllegalArgumentException}. 348 * 349 * <p>If this {@code Field} object is enforcing Java language access control, and 350 * the underlying field is inaccessible, the method throws an 351 * {@code IllegalAccessException}. 352 * If the underlying field is static, the class that declared the 353 * field is initialized if it has not already been initialized. 354 * 355 * <p>Otherwise, the value is retrieved from the underlying instance 356 * or static field. If the field has a primitive type, the value 357 * is wrapped in an object before being returned, otherwise it is 358 * returned as is. 359 * 360 * <p>If the field is hidden in the type of {@code obj}, 361 * the field's value is obtained according to the preceding rules. 362 * 363 * @param obj object from which the represented field's value is 364 * to be extracted 365 * @return the value of the represented field in object 366 * {@code obj}; primitive values are wrapped in an appropriate 367 * object before being returned 368 * 369 * @exception IllegalAccessException if this {@code Field} object 370 * is enforcing Java language access control and the underlying 371 * field is inaccessible. 372 * @exception IllegalArgumentException if the specified object is not an 373 * instance of the class or interface declaring the underlying 374 * field (or a subclass or implementor thereof). 375 * @exception NullPointerException if the specified object is null 376 * and the field is an instance field. 377 * @exception ExceptionInInitializerError if the initialization provoked 378 * by this method fails. 379 */ 380 public Object get(Object obj) 381 throws IllegalArgumentException, IllegalAccessException 382 { 383 return getFieldAccessor(obj).get(obj); 384 } 385 386 /** 387 * Gets the value of a static or instance {@code boolean} field. 388 * 389 * @param obj the object to extract the {@code boolean} value 390 * from 391 * @return the value of the {@code boolean} field 392 * 393 * @exception IllegalAccessException if this {@code Field} object 394 * is enforcing Java language access control and the underlying 395 * field is inaccessible. 396 * @exception IllegalArgumentException if the specified object is not 397 * an instance of the class or interface declaring the 398 * underlying field (or a subclass or implementor 399 * thereof), or if the field value cannot be 400 * converted to the type {@code boolean} by a 401 * widening conversion. 402 * @exception NullPointerException if the specified object is null 403 * and the field is an instance field. 404 * @exception ExceptionInInitializerError if the initialization provoked 405 * by this method fails. 406 * @see Field#get 407 */ 408 public boolean getBoolean(Object obj) 409 throws IllegalArgumentException, IllegalAccessException 410 { 411 return getFieldAccessor(obj).getBoolean(obj); 412 } 413 414 /** 415 * Gets the value of a static or instance {@code byte} field. 416 * 417 * @param obj the object to extract the {@code byte} value 418 * from 419 * @return the value of the {@code byte} field 420 * 421 * @exception IllegalAccessException if this {@code Field} object 422 * is enforcing Java language access control and the underlying 423 * field is inaccessible. 424 * @exception IllegalArgumentException if the specified object is not 425 * an instance of the class or interface declaring the 426 * underlying field (or a subclass or implementor 427 * thereof), or if the field value cannot be 428 * converted to the type {@code byte} by a 429 * widening conversion. 430 * @exception NullPointerException if the specified object is null 431 * and the field is an instance field. 432 * @exception ExceptionInInitializerError if the initialization provoked 433 * by this method fails. 434 * @see Field#get 435 */ 436 public byte getByte(Object obj) 437 throws IllegalArgumentException, IllegalAccessException 438 { 439 return getFieldAccessor(obj).getByte(obj); 440 } 441 442 /** 443 * Gets the value of a static or instance field of type 444 * {@code char} or of another primitive type convertible to 445 * type {@code char} via a widening conversion. 446 * 447 * @param obj the object to extract the {@code char} value 448 * from 449 * @return the value of the field converted to type {@code char} 450 * 451 * @exception IllegalAccessException if this {@code Field} object 452 * is enforcing Java language access control and the underlying 453 * field is inaccessible. 454 * @exception IllegalArgumentException if the specified object is not 455 * an instance of the class or interface declaring the 456 * underlying field (or a subclass or implementor 457 * thereof), or if the field value cannot be 458 * converted to the type {@code char} by a 459 * widening conversion. 460 * @exception NullPointerException if the specified object is null 461 * and the field is an instance field. 462 * @exception ExceptionInInitializerError if the initialization provoked 463 * by this method fails. 464 * @see Field#get 465 */ 466 public char getChar(Object obj) 467 throws IllegalArgumentException, IllegalAccessException 468 { 469 return getFieldAccessor(obj).getChar(obj); 470 } 471 472 /** 473 * Gets the value of a static or instance field of type 474 * {@code short} or of another primitive type convertible to 475 * type {@code short} via a widening conversion. 476 * 477 * @param obj the object to extract the {@code short} value 478 * from 479 * @return the value of the field converted to type {@code short} 480 * 481 * @exception IllegalAccessException if this {@code Field} object 482 * is enforcing Java language access control and the underlying 483 * field is inaccessible. 484 * @exception IllegalArgumentException if the specified object is not 485 * an instance of the class or interface declaring the 486 * underlying field (or a subclass or implementor 487 * thereof), or if the field value cannot be 488 * converted to the type {@code short} by a 489 * widening conversion. 490 * @exception NullPointerException if the specified object is null 491 * and the field is an instance field. 492 * @exception ExceptionInInitializerError if the initialization provoked 493 * by this method fails. 494 * @see Field#get 495 */ 496 public short getShort(Object obj) 497 throws IllegalArgumentException, IllegalAccessException 498 { 499 return getFieldAccessor(obj).getShort(obj); 500 } 501 502 /** 503 * Gets the value of a static or instance field of type 504 * {@code int} or of another primitive type convertible to 505 * type {@code int} via a widening conversion. 506 * 507 * @param obj the object to extract the {@code int} value 508 * from 509 * @return the value of the field converted to type {@code int} 510 * 511 * @exception IllegalAccessException if this {@code Field} object 512 * is enforcing Java language access control and the underlying 513 * field is inaccessible. 514 * @exception IllegalArgumentException if the specified object is not 515 * an instance of the class or interface declaring the 516 * underlying field (or a subclass or implementor 517 * thereof), or if the field value cannot be 518 * converted to the type {@code int} by a 519 * widening conversion. 520 * @exception NullPointerException if the specified object is null 521 * and the field is an instance field. 522 * @exception ExceptionInInitializerError if the initialization provoked 523 * by this method fails. 524 * @see Field#get 525 */ 526 public int getInt(Object obj) 527 throws IllegalArgumentException, IllegalAccessException 528 { 529 return getFieldAccessor(obj).getInt(obj); 530 } 531 532 /** 533 * Gets the value of a static or instance field of type 534 * {@code long} or of another primitive type convertible to 535 * type {@code long} via a widening conversion. 536 * 537 * @param obj the object to extract the {@code long} value 538 * from 539 * @return the value of the field converted to type {@code long} 540 * 541 * @exception IllegalAccessException if this {@code Field} object 542 * is enforcing Java language access control and the underlying 543 * field is inaccessible. 544 * @exception IllegalArgumentException if the specified object is not 545 * an instance of the class or interface declaring the 546 * underlying field (or a subclass or implementor 547 * thereof), or if the field value cannot be 548 * converted to the type {@code long} by a 549 * widening conversion. 550 * @exception NullPointerException if the specified object is null 551 * and the field is an instance field. 552 * @exception ExceptionInInitializerError if the initialization provoked 553 * by this method fails. 554 * @see Field#get 555 */ 556 public long getLong(Object obj) 557 throws IllegalArgumentException, IllegalAccessException 558 { 559 return getFieldAccessor(obj).getLong(obj); 560 } 561 562 /** 563 * Gets the value of a static or instance field of type 564 * {@code float} or of another primitive type convertible to 565 * type {@code float} via a widening conversion. 566 * 567 * @param obj the object to extract the {@code float} value 568 * from 569 * @return the value of the field converted to type {@code float} 570 * 571 * @exception IllegalAccessException if this {@code Field} object 572 * is enforcing Java language access control and the underlying 573 * field is inaccessible. 574 * @exception IllegalArgumentException if the specified object is not 575 * an instance of the class or interface declaring the 576 * underlying field (or a subclass or implementor 577 * thereof), or if the field value cannot be 578 * converted to the type {@code float} by a 579 * widening conversion. 580 * @exception NullPointerException if the specified object is null 581 * and the field is an instance field. 582 * @exception ExceptionInInitializerError if the initialization provoked 583 * by this method fails. 584 * @see Field#get 585 */ 586 public float getFloat(Object obj) 587 throws IllegalArgumentException, IllegalAccessException 588 { 589 return getFieldAccessor(obj).getFloat(obj); 590 } 591 592 /** 593 * Gets the value of a static or instance field of type 594 * {@code double} or of another primitive type convertible to 595 * type {@code double} via a widening conversion. 596 * 597 * @param obj the object to extract the {@code double} value 598 * from 599 * @return the value of the field converted to type {@code double} 600 * 601 * @exception IllegalAccessException if this {@code Field} object 602 * is enforcing Java language access control and the underlying 603 * field is inaccessible. 604 * @exception IllegalArgumentException if the specified object is not 605 * an instance of the class or interface declaring the 606 * underlying field (or a subclass or implementor 607 * thereof), or if the field value cannot be 608 * converted to the type {@code double} by a 609 * widening conversion. 610 * @exception NullPointerException if the specified object is null 611 * and the field is an instance field. 612 * @exception ExceptionInInitializerError if the initialization provoked 613 * by this method fails. 614 * @see Field#get 615 */ 616 public double getDouble(Object obj) 617 throws IllegalArgumentException, IllegalAccessException 618 { 619 return getFieldAccessor(obj).getDouble(obj); 620 } 621 622 /** 623 * Sets the field represented by this {@code Field} object on the 624 * specified object argument to the specified new value. The new 625 * value is automatically unwrapped if the underlying field has a 626 * primitive type. 627 * 628 * <p>The operation proceeds as follows: 629 * 630 * <p>If the underlying field is static, the {@code obj} argument is 631 * ignored; it may be null. 632 * 633 * <p>Otherwise the underlying field is an instance field. If the 634 * specified object argument is null, the method throws a 635 * {@code NullPointerException}. If the specified object argument is not 636 * an instance of the class or interface declaring the underlying 637 * field, the method throws an {@code IllegalArgumentException}. 638 * 639 * <p>If this {@code Field} object is enforcing Java language access control, and 640 * the underlying field is inaccessible, the method throws an 641 * {@code IllegalAccessException}. 642 * 643 * <p>If the underlying field is final, the method throws an 644 * {@code IllegalAccessException} unless {@code setAccessible(true)} 645 * has succeeded for this {@code Field} object 646 * and the field is non-static. Setting a final field in this way 647 * is meaningful only during deserialization or reconstruction of 648 * instances of classes with blank final fields, before they are 649 * made available for access by other parts of a program. Use in 650 * any other context may have unpredictable effects, including cases 651 * in which other parts of a program continue to use the original 652 * value of this field. 653 * 654 * <p>If the underlying field is of a primitive type, an unwrapping 655 * conversion is attempted to convert the new value to a value of 656 * a primitive type. If this attempt fails, the method throws an 657 * {@code IllegalArgumentException}. 658 * 659 * <p>If, after possible unwrapping, the new value cannot be 660 * converted to the type of the underlying field by an identity or 661 * widening conversion, the method throws an 662 * {@code IllegalArgumentException}. 663 * 664 * <p>If the underlying field is static, the class that declared the 665 * field is initialized if it has not already been initialized. 666 * 667 * <p>The field is set to the possibly unwrapped and widened new value. 668 * 669 * <p>If the field is hidden in the type of {@code obj}, 670 * the field's value is set according to the preceding rules. 671 * 672 * @param obj the object whose field should be modified 673 * @param value the new value for the field of {@code obj} 674 * being modified 675 * 676 * @exception IllegalAccessException if this {@code Field} object 677 * is enforcing Java language access control and the underlying 678 * field is either inaccessible or final. 679 * @exception IllegalArgumentException if the specified object is not an 680 * instance of the class or interface declaring the underlying 681 * field (or a subclass or implementor thereof), 682 * or if an unwrapping conversion fails. 683 * @exception NullPointerException if the specified object is null 684 * and the field is an instance field. 685 * @exception ExceptionInInitializerError if the initialization provoked 686 * by this method fails. 687 */ 688 public void set(Object obj, Object value) 689 throws IllegalArgumentException, IllegalAccessException 690 { 691 getFieldAccessor(obj).set(obj, value); 692 } 693 694 /** 695 * Sets the value of a field as a {@code boolean} on the specified object. 696 * This method is equivalent to 697 * {@code set(obj, zObj)}, 698 * where {@code zObj} is a {@code Boolean} object and 699 * {@code zObj.booleanValue() == z}. 700 * 701 * @param obj the object whose field should be modified 702 * @param z the new value for the field of {@code obj} 703 * being modified 704 * 705 * @exception IllegalAccessException if this {@code Field} object 706 * is enforcing Java language access control and the underlying 707 * field is either inaccessible or final. 708 * @exception IllegalArgumentException if the specified object is not an 709 * instance of the class or interface declaring the underlying 710 * field (or a subclass or implementor thereof), 711 * or if an unwrapping conversion fails. 712 * @exception NullPointerException if the specified object is null 713 * and the field is an instance field. 714 * @exception ExceptionInInitializerError if the initialization provoked 715 * by this method fails. 716 * @see Field#set 717 */ 718 public void setBoolean(Object obj, boolean z) 719 throws IllegalArgumentException, IllegalAccessException 720 { 721 getFieldAccessor(obj).setBoolean(obj, z); 722 } 723 724 /** 725 * Sets the value of a field as a {@code byte} on the specified object. 726 * This method is equivalent to 727 * {@code set(obj, bObj)}, 728 * where {@code bObj} is a {@code Byte} object and 729 * {@code bObj.byteValue() == b}. 730 * 731 * @param obj the object whose field should be modified 732 * @param b the new value for the field of {@code obj} 733 * being modified 734 * 735 * @exception IllegalAccessException if this {@code Field} object 736 * is enforcing Java language access control and the underlying 737 * field is either inaccessible or final. 738 * @exception IllegalArgumentException if the specified object is not an 739 * instance of the class or interface declaring the underlying 740 * field (or a subclass or implementor thereof), 741 * or if an unwrapping conversion fails. 742 * @exception NullPointerException if the specified object is null 743 * and the field is an instance field. 744 * @exception ExceptionInInitializerError if the initialization provoked 745 * by this method fails. 746 * @see Field#set 747 */ 748 public void setByte(Object obj, byte b) 749 throws IllegalArgumentException, IllegalAccessException 750 { 751 getFieldAccessor(obj).setByte(obj, b); 752 } 753 754 /** 755 * Sets the value of a field as a {@code char} on the specified object. 756 * This method is equivalent to 757 * {@code set(obj, cObj)}, 758 * where {@code cObj} is a {@code Character} object and 759 * {@code cObj.charValue() == c}. 760 * 761 * @param obj the object whose field should be modified 762 * @param c the new value for the field of {@code obj} 763 * being modified 764 * 765 * @exception IllegalAccessException if this {@code Field} object 766 * is enforcing Java language access control and the underlying 767 * field is either inaccessible or final. 768 * @exception IllegalArgumentException if the specified object is not an 769 * instance of the class or interface declaring the underlying 770 * field (or a subclass or implementor thereof), 771 * or if an unwrapping conversion fails. 772 * @exception NullPointerException if the specified object is null 773 * and the field is an instance field. 774 * @exception ExceptionInInitializerError if the initialization provoked 775 * by this method fails. 776 * @see Field#set 777 */ 778 public void setChar(Object obj, char c) 779 throws IllegalArgumentException, IllegalAccessException 780 { 781 getFieldAccessor(obj).setChar(obj, c); 782 } 783 784 /** 785 * Sets the value of a field as a {@code short} on the specified object. 786 * This method is equivalent to 787 * {@code set(obj, sObj)}, 788 * where {@code sObj} is a {@code Short} object and 789 * {@code sObj.shortValue() == s}. 790 * 791 * @param obj the object whose field should be modified 792 * @param s the new value for the field of {@code obj} 793 * being modified 794 * 795 * @exception IllegalAccessException if this {@code Field} object 796 * is enforcing Java language access control and the underlying 797 * field is either inaccessible or final. 798 * @exception IllegalArgumentException if the specified object is not an 799 * instance of the class or interface declaring the underlying 800 * field (or a subclass or implementor thereof), 801 * or if an unwrapping conversion fails. 802 * @exception NullPointerException if the specified object is null 803 * and the field is an instance field. 804 * @exception ExceptionInInitializerError if the initialization provoked 805 * by this method fails. 806 * @see Field#set 807 */ 808 public void setShort(Object obj, short s) 809 throws IllegalArgumentException, IllegalAccessException 810 { 811 getFieldAccessor(obj).setShort(obj, s); 812 } 813 814 /** 815 * Sets the value of a field as an {@code int} on the specified object. 816 * This method is equivalent to 817 * {@code set(obj, iObj)}, 818 * where {@code iObj} is a {@code Integer} object and 819 * {@code iObj.intValue() == i}. 820 * 821 * @param obj the object whose field should be modified 822 * @param i the new value for the field of {@code obj} 823 * being modified 824 * 825 * @exception IllegalAccessException if this {@code Field} object 826 * is enforcing Java language access control and the underlying 827 * field is either inaccessible or final. 828 * @exception IllegalArgumentException if the specified object is not an 829 * instance of the class or interface declaring the underlying 830 * field (or a subclass or implementor thereof), 831 * or if an unwrapping conversion fails. 832 * @exception NullPointerException if the specified object is null 833 * and the field is an instance field. 834 * @exception ExceptionInInitializerError if the initialization provoked 835 * by this method fails. 836 * @see Field#set 837 */ 838 public void setInt(Object obj, int i) 839 throws IllegalArgumentException, IllegalAccessException 840 { 841 getFieldAccessor(obj).setInt(obj, i); 842 } 843 844 /** 845 * Sets the value of a field as a {@code long} on the specified object. 846 * This method is equivalent to 847 * {@code set(obj, lObj)}, 848 * where {@code lObj} is a {@code Long} object and 849 * {@code lObj.longValue() == l}. 850 * 851 * @param obj the object whose field should be modified 852 * @param l the new value for the field of {@code obj} 853 * being modified 854 * 855 * @exception IllegalAccessException if this {@code Field} object 856 * is enforcing Java language access control and the underlying 857 * field is either inaccessible or final. 858 * @exception IllegalArgumentException if the specified object is not an 859 * instance of the class or interface declaring the underlying 860 * field (or a subclass or implementor thereof), 861 * or if an unwrapping conversion fails. 862 * @exception NullPointerException if the specified object is null 863 * and the field is an instance field. 864 * @exception ExceptionInInitializerError if the initialization provoked 865 * by this method fails. 866 * @see Field#set 867 */ 868 public void setLong(Object obj, long l) 869 throws IllegalArgumentException, IllegalAccessException 870 { 871 getFieldAccessor(obj).setLong(obj, l); 872 } 873 874 /** 875 * Sets the value of a field as a {@code float} on the specified object. 876 * This method is equivalent to 877 * {@code set(obj, fObj)}, 878 * where {@code fObj} is a {@code Float} object and 879 * {@code fObj.floatValue() == f}. 880 * 881 * @param obj the object whose field should be modified 882 * @param f the new value for the field of {@code obj} 883 * being modified 884 * 885 * @exception IllegalAccessException if this {@code Field} object 886 * is enforcing Java language access control and the underlying 887 * field is either inaccessible or final. 888 * @exception IllegalArgumentException if the specified object is not an 889 * instance of the class or interface declaring the underlying 890 * field (or a subclass or implementor thereof), 891 * or if an unwrapping conversion fails. 892 * @exception NullPointerException if the specified object is null 893 * and the field is an instance field. 894 * @exception ExceptionInInitializerError if the initialization provoked 895 * by this method fails. 896 * @see Field#set 897 */ 898 public void setFloat(Object obj, float f) 899 throws IllegalArgumentException, IllegalAccessException 900 { 901 getFieldAccessor(obj).setFloat(obj, f); 902 } 903 904 /** 905 * Sets the value of a field as a {@code double} on the specified object. 906 * This method is equivalent to 907 * {@code set(obj, dObj)}, 908 * where {@code dObj} is a {@code Double} object and 909 * {@code dObj.doubleValue() == d}. 910 * 911 * @param obj the object whose field should be modified 912 * @param d the new value for the field of {@code obj} 913 * being modified 914 * 915 * @exception IllegalAccessException if this {@code Field} object 916 * is enforcing Java language access control and the underlying 917 * field is either inaccessible or final. 918 * @exception IllegalArgumentException if the specified object is not an 919 * instance of the class or interface declaring the underlying 920 * field (or a subclass or implementor thereof), 921 * or if an unwrapping conversion fails. 922 * @exception NullPointerException if the specified object is null 923 * and the field is an instance field. 924 * @exception ExceptionInInitializerError if the initialization provoked 925 * by this method fails. 926 * @see Field#set 927 */ 928 public void setDouble(Object obj, double d) 929 throws IllegalArgumentException, IllegalAccessException 930 { 931 getFieldAccessor(obj).setDouble(obj, d); 932 } 933 934 // Convenience routine which performs security checks 935 private FieldAccessor getFieldAccessor(Object obj) 936 throws IllegalAccessException 937 { 938 doSecurityCheck(obj); 939 boolean ov = override; 940 FieldAccessor a = (ov)? overrideFieldAccessor : fieldAccessor; 941 return (a != null)? a : acquireFieldAccessor(ov); 942 } 943 944 // NOTE that there is no synchronization used here. It is correct 945 // (though not efficient) to generate more than one FieldAccessor 946 // for a given Field. However, avoiding synchronization will 947 // probably make the implementation more scalable. 948 private FieldAccessor acquireFieldAccessor(boolean overrideFinalCheck) { 949 // First check to see if one has been created yet, and take it 950 // if so 951 FieldAccessor tmp = null; 952 if (root != null) tmp = root.getFieldAccessor(overrideFinalCheck); 953 if (tmp != null) { 954 if (overrideFinalCheck) 955 overrideFieldAccessor = tmp; 956 else 957 fieldAccessor = tmp; 958 } else { 959 // Otherwise fabricate one and propagate it up to the root 960 tmp = reflectionFactory.newFieldAccessor(this, overrideFinalCheck); 961 setFieldAccessor(tmp, overrideFinalCheck); 962 } 963 964 return tmp; 965 } 966 967 // Returns FieldAccessor for this Field object, not looking up 968 // the chain to the root 969 private FieldAccessor getFieldAccessor(boolean overrideFinalCheck) { 970 return (overrideFinalCheck)? overrideFieldAccessor : fieldAccessor; 971 } 972 973 // Sets the FieldAccessor for this Field object and 974 // (recursively) its root 975 private void setFieldAccessor(FieldAccessor accessor, boolean overrideFinalCheck) { 976 if (overrideFinalCheck) 977 overrideFieldAccessor = accessor; 978 else 979 fieldAccessor = accessor; 980 // Propagate up 981 if (root != null) { 982 root.setFieldAccessor(accessor, overrideFinalCheck); 983 } 984 } 985 986 // NOTE: be very careful if you change the stack depth of this 987 // routine. The depth of the "getCallerClass" call is hardwired so 988 // that the compiler can have an easier time if this gets inlined. 989 private void doSecurityCheck(Object obj) throws IllegalAccessException { 990 if (!override) { 991 if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { 992 Class<?> caller = Reflection.getCallerClass(4); 993 994 checkAccess(caller, clazz, obj, modifiers); 995 } 996 } 997 } 998 999 /* 1000 * Utility routine to paper over array type names 1001 */ 1002 static String getTypeName(Class<?> type) { 1003 if (type.isArray()) { 1004 try { 1005 Class<?> cl = type; 1006 int dimensions = 0; 1007 while (cl.isArray()) { 1008 dimensions++; 1009 cl = cl.getComponentType(); 1010 } 1011 StringBuffer sb = new StringBuffer(); 1012 sb.append(cl.getName()); 1013 for (int i = 0; i < dimensions; i++) { 1014 sb.append("[]"); 1015 } 1016 return sb.toString(); 1017 } catch (Throwable e) { /*FALLTHRU*/ } 1018 } 1019 return type.getName(); 1020 } 1021 1022 /** 1023 * @throws NullPointerException {@inheritDoc} 1024 * @since 1.5 1025 */ 1026 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { 1027 Objects.requireNonNull(annotationClass); 1028 return annotationClass.cast(declaredAnnotations().get(annotationClass)); 1029 } 1030 1031 /** 1032 * {@inheritDoc} 1033 * @throws NullPointerException {@inheritDoc} 1034 * @since 1.8 1035 */ 1036 @Override 1037 public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) { 1038 Objects.requireNonNull(annotationClass); 1039 1040 return AnnotationSupport.getMultipleAnnotations(declaredAnnotations(), annotationClass); 1041 } 1042 1043 /** 1044 * {@inheritDoc} 1045 */ 1046 public Annotation[] getDeclaredAnnotations() { 1047 return AnnotationParser.toArray(declaredAnnotations()); 1048 } 1049 1050 private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations; 1051 1052 private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() { 1053 if (declaredAnnotations == null) { 1054 declaredAnnotations = AnnotationParser.parseAnnotations( 1055 annotations, sun.misc.SharedSecrets.getJavaLangAccess(). 1056 getConstantPool(getDeclaringClass()), 1057 getDeclaringClass()); 1058 } 1059 return declaredAnnotations; 1060 } 1061 1062 /** 1063 * Returns an AnnotatedType object that represents the use of a type to specify 1064 * the declared type of the field represented by this Field. 1065 * 1066 * @since 1.8 1067 */ 1068 public AnnotatedType getAnnotatedType() { 1069 return TypeAnnotationParser.buildAnnotatedType(typeAnnotations, 1070 sun.misc.SharedSecrets.getJavaLangAccess(). 1071 getConstantPool(getDeclaringClass()), 1072 this, 1073 getDeclaringClass(), 1074 getGenericType(), 1075 TypeAnnotation.TypeAnnotationTarget.FIELD_TYPE); 1076 } 1077 }