1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/emul/mini/src/main/java/java/lang/reflect/Field.java Wed Jan 23 20:39:23 2013 +0100
1.3 @@ -0,0 +1,953 @@
1.4 +/*
1.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.lang.reflect;
1.30 +
1.31 +import java.lang.annotation.Annotation;
1.32 +
1.33 +
1.34 +/**
1.35 + * A {@code Field} provides information about, and dynamic access to, a
1.36 + * single field of a class or an interface. The reflected field may
1.37 + * be a class (static) field or an instance field.
1.38 + *
1.39 + * <p>A {@code Field} permits widening conversions to occur during a get or
1.40 + * set access operation, but throws an {@code IllegalArgumentException} if a
1.41 + * narrowing conversion would occur.
1.42 + *
1.43 + * @see Member
1.44 + * @see java.lang.Class
1.45 + * @see java.lang.Class#getFields()
1.46 + * @see java.lang.Class#getField(String)
1.47 + * @see java.lang.Class#getDeclaredFields()
1.48 + * @see java.lang.Class#getDeclaredField(String)
1.49 + *
1.50 + * @author Kenneth Russell
1.51 + * @author Nakul Saraiya
1.52 + */
1.53 +public final
1.54 +class Field extends AccessibleObject implements Member {
1.55 +
1.56 + private Class<?> clazz;
1.57 + private int slot;
1.58 + // This is guaranteed to be interned by the VM in the 1.4
1.59 + // reflection implementation
1.60 + private String name;
1.61 + private Class<?> type;
1.62 + private int modifiers;
1.63 + // Generics and annotations support
1.64 + private transient String signature;
1.65 + private byte[] annotations;
1.66 + // For sharing of FieldAccessors. This branching structure is
1.67 + // currently only two levels deep (i.e., one root Field and
1.68 + // potentially many Field objects pointing to it.)
1.69 + private Field root;
1.70 +
1.71 + // Generics infrastructure
1.72 +
1.73 + private String getGenericSignature() {return signature;}
1.74 +
1.75 +
1.76 + /**
1.77 + * Package-private constructor used by ReflectAccess to enable
1.78 + * instantiation of these objects in Java code from the java.lang
1.79 + * package via sun.reflect.LangReflectAccess.
1.80 + */
1.81 + Field(Class<?> declaringClass,
1.82 + String name,
1.83 + Class<?> type,
1.84 + int modifiers,
1.85 + int slot,
1.86 + String signature,
1.87 + byte[] annotations)
1.88 + {
1.89 + this.clazz = declaringClass;
1.90 + this.name = name;
1.91 + this.type = type;
1.92 + this.modifiers = modifiers;
1.93 + this.slot = slot;
1.94 + this.signature = signature;
1.95 + this.annotations = annotations;
1.96 + }
1.97 +
1.98 + /**
1.99 + * Package-private routine (exposed to java.lang.Class via
1.100 + * ReflectAccess) which returns a copy of this Field. The copy's
1.101 + * "root" field points to this Field.
1.102 + */
1.103 + Field copy() {
1.104 + // This routine enables sharing of FieldAccessor objects
1.105 + // among Field objects which refer to the same underlying
1.106 + // method in the VM. (All of this contortion is only necessary
1.107 + // because of the "accessibility" bit in AccessibleObject,
1.108 + // which implicitly requires that new java.lang.reflect
1.109 + // objects be fabricated for each reflective call on Class
1.110 + // objects.)
1.111 + Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations);
1.112 + res.root = this;
1.113 + return res;
1.114 + }
1.115 +
1.116 + /**
1.117 + * Returns the {@code Class} object representing the class or interface
1.118 + * that declares the field represented by this {@code Field} object.
1.119 + */
1.120 + public Class<?> getDeclaringClass() {
1.121 + return clazz;
1.122 + }
1.123 +
1.124 + /**
1.125 + * Returns the name of the field represented by this {@code Field} object.
1.126 + */
1.127 + public String getName() {
1.128 + return name;
1.129 + }
1.130 +
1.131 + /**
1.132 + * Returns the Java language modifiers for the field represented
1.133 + * by this {@code Field} object, as an integer. The {@code Modifier} class should
1.134 + * be used to decode the modifiers.
1.135 + *
1.136 + * @see Modifier
1.137 + */
1.138 + public int getModifiers() {
1.139 + return modifiers;
1.140 + }
1.141 +
1.142 + /**
1.143 + * Returns {@code true} if this field represents an element of
1.144 + * an enumerated type; returns {@code false} otherwise.
1.145 + *
1.146 + * @return {@code true} if and only if this field represents an element of
1.147 + * an enumerated type.
1.148 + * @since 1.5
1.149 + */
1.150 + public boolean isEnumConstant() {
1.151 + return (getModifiers() & Modifier.ENUM) != 0;
1.152 + }
1.153 +
1.154 + /**
1.155 + * Returns {@code true} if this field is a synthetic
1.156 + * field; returns {@code false} otherwise.
1.157 + *
1.158 + * @return true if and only if this field is a synthetic
1.159 + * field as defined by the Java Language Specification.
1.160 + * @since 1.5
1.161 + */
1.162 + public boolean isSynthetic() {
1.163 + return Modifier.isSynthetic(getModifiers());
1.164 + }
1.165 +
1.166 + /**
1.167 + * Returns a {@code Class} object that identifies the
1.168 + * declared type for the field represented by this
1.169 + * {@code Field} object.
1.170 + *
1.171 + * @return a {@code Class} object identifying the declared
1.172 + * type of the field represented by this object
1.173 + */
1.174 + public Class<?> getType() {
1.175 + return type;
1.176 + }
1.177 +
1.178 + /**
1.179 + * Returns a {@code Type} object that represents the declared type for
1.180 + * the field represented by this {@code Field} object.
1.181 + *
1.182 + * <p>If the {@code Type} is a parameterized type, the
1.183 + * {@code Type} object returned must accurately reflect the
1.184 + * actual type parameters used in the source code.
1.185 + *
1.186 + * <p>If the type of the underlying field is a type variable or a
1.187 + * parameterized type, it is created. Otherwise, it is resolved.
1.188 + *
1.189 + * @return a {@code Type} object that represents the declared type for
1.190 + * the field represented by this {@code Field} object
1.191 + * @throws GenericSignatureFormatError if the generic field
1.192 + * signature does not conform to the format specified in
1.193 + * <cite>The Java™ Virtual Machine Specification</cite>
1.194 + * @throws TypeNotPresentException if the generic type
1.195 + * signature of the underlying field refers to a non-existent
1.196 + * type declaration
1.197 + * @throws MalformedParameterizedTypeException if the generic
1.198 + * signature of the underlying field refers to a parameterized type
1.199 + * that cannot be instantiated for any reason
1.200 + * @since 1.5
1.201 + */
1.202 + public Type getGenericType() {
1.203 + throw new UnsupportedOperationException();
1.204 + }
1.205 +
1.206 +
1.207 + /**
1.208 + * Compares this {@code Field} against the specified object. Returns
1.209 + * true if the objects are the same. Two {@code Field} objects are the same if
1.210 + * they were declared by the same class and have the same name
1.211 + * and type.
1.212 + */
1.213 + public boolean equals(Object obj) {
1.214 + if (obj != null && obj instanceof Field) {
1.215 + Field other = (Field)obj;
1.216 + return (getDeclaringClass() == other.getDeclaringClass())
1.217 + && (getName() == other.getName())
1.218 + && (getType() == other.getType());
1.219 + }
1.220 + return false;
1.221 + }
1.222 +
1.223 + /**
1.224 + * Returns a hashcode for this {@code Field}. This is computed as the
1.225 + * exclusive-or of the hashcodes for the underlying field's
1.226 + * declaring class name and its name.
1.227 + */
1.228 + public int hashCode() {
1.229 + return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
1.230 + }
1.231 +
1.232 + /**
1.233 + * Returns a string describing this {@code Field}. The format is
1.234 + * the access modifiers for the field, if any, followed
1.235 + * by the field type, followed by a space, followed by
1.236 + * the fully-qualified name of the class declaring the field,
1.237 + * followed by a period, followed by the name of the field.
1.238 + * For example:
1.239 + * <pre>
1.240 + * public static final int java.lang.Thread.MIN_PRIORITY
1.241 + * private int java.io.FileDescriptor.fd
1.242 + * </pre>
1.243 + *
1.244 + * <p>The modifiers are placed in canonical order as specified by
1.245 + * "The Java Language Specification". This is {@code public},
1.246 + * {@code protected} or {@code private} first, and then other
1.247 + * modifiers in the following order: {@code static}, {@code final},
1.248 + * {@code transient}, {@code volatile}.
1.249 + */
1.250 + public String toString() {
1.251 + int mod = getModifiers();
1.252 + return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
1.253 + + getTypeName(getType()) + " "
1.254 + + getTypeName(getDeclaringClass()) + "."
1.255 + + getName());
1.256 + }
1.257 +
1.258 + /**
1.259 + * Returns a string describing this {@code Field}, including
1.260 + * its generic type. The format is the access modifiers for the
1.261 + * field, if any, followed by the generic field type, followed by
1.262 + * a space, followed by the fully-qualified name of the class
1.263 + * declaring the field, followed by a period, followed by the name
1.264 + * of the field.
1.265 + *
1.266 + * <p>The modifiers are placed in canonical order as specified by
1.267 + * "The Java Language Specification". This is {@code public},
1.268 + * {@code protected} or {@code private} first, and then other
1.269 + * modifiers in the following order: {@code static}, {@code final},
1.270 + * {@code transient}, {@code volatile}.
1.271 + *
1.272 + * @return a string describing this {@code Field}, including
1.273 + * its generic type
1.274 + *
1.275 + * @since 1.5
1.276 + */
1.277 + public String toGenericString() {
1.278 + int mod = getModifiers();
1.279 + Type fieldType = getGenericType();
1.280 + return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
1.281 + + ((fieldType instanceof Class) ?
1.282 + getTypeName((Class)fieldType): fieldType.toString())+ " "
1.283 + + getTypeName(getDeclaringClass()) + "."
1.284 + + getName());
1.285 + }
1.286 +
1.287 + /**
1.288 + * Returns the value of the field represented by this {@code Field}, on
1.289 + * the specified object. The value is automatically wrapped in an
1.290 + * object if it has a primitive type.
1.291 + *
1.292 + * <p>The underlying field's value is obtained as follows:
1.293 + *
1.294 + * <p>If the underlying field is a static field, the {@code obj} argument
1.295 + * is ignored; it may be null.
1.296 + *
1.297 + * <p>Otherwise, the underlying field is an instance field. If the
1.298 + * specified {@code obj} argument is null, the method throws a
1.299 + * {@code NullPointerException}. If the specified object is not an
1.300 + * instance of the class or interface declaring the underlying
1.301 + * field, the method throws an {@code IllegalArgumentException}.
1.302 + *
1.303 + * <p>If this {@code Field} object is enforcing Java language access control, and
1.304 + * the underlying field is inaccessible, the method throws an
1.305 + * {@code IllegalAccessException}.
1.306 + * If the underlying field is static, the class that declared the
1.307 + * field is initialized if it has not already been initialized.
1.308 + *
1.309 + * <p>Otherwise, the value is retrieved from the underlying instance
1.310 + * or static field. If the field has a primitive type, the value
1.311 + * is wrapped in an object before being returned, otherwise it is
1.312 + * returned as is.
1.313 + *
1.314 + * <p>If the field is hidden in the type of {@code obj},
1.315 + * the field's value is obtained according to the preceding rules.
1.316 + *
1.317 + * @param obj object from which the represented field's value is
1.318 + * to be extracted
1.319 + * @return the value of the represented field in object
1.320 + * {@code obj}; primitive values are wrapped in an appropriate
1.321 + * object before being returned
1.322 + *
1.323 + * @exception IllegalAccessException if this {@code Field} object
1.324 + * is enforcing Java language access control and the underlying
1.325 + * field is inaccessible.
1.326 + * @exception IllegalArgumentException if the specified object is not an
1.327 + * instance of the class or interface declaring the underlying
1.328 + * field (or a subclass or implementor thereof).
1.329 + * @exception NullPointerException if the specified object is null
1.330 + * and the field is an instance field.
1.331 + * @exception ExceptionInInitializerError if the initialization provoked
1.332 + * by this method fails.
1.333 + */
1.334 + public Object get(Object obj)
1.335 + throws IllegalArgumentException, IllegalAccessException
1.336 + {
1.337 + return getFieldAccessor(obj).get(obj);
1.338 + }
1.339 +
1.340 + /**
1.341 + * Gets the value of a static or instance {@code boolean} field.
1.342 + *
1.343 + * @param obj the object to extract the {@code boolean} value
1.344 + * from
1.345 + * @return the value of the {@code boolean} field
1.346 + *
1.347 + * @exception IllegalAccessException if this {@code Field} object
1.348 + * is enforcing Java language access control and the underlying
1.349 + * field is inaccessible.
1.350 + * @exception IllegalArgumentException if the specified object is not
1.351 + * an instance of the class or interface declaring the
1.352 + * underlying field (or a subclass or implementor
1.353 + * thereof), or if the field value cannot be
1.354 + * converted to the type {@code boolean} by a
1.355 + * widening conversion.
1.356 + * @exception NullPointerException if the specified object is null
1.357 + * and the field is an instance field.
1.358 + * @exception ExceptionInInitializerError if the initialization provoked
1.359 + * by this method fails.
1.360 + * @see Field#get
1.361 + */
1.362 + public boolean getBoolean(Object obj)
1.363 + throws IllegalArgumentException, IllegalAccessException
1.364 + {
1.365 + return getFieldAccessor(obj).getBoolean(obj);
1.366 + }
1.367 +
1.368 + /**
1.369 + * Gets the value of a static or instance {@code byte} field.
1.370 + *
1.371 + * @param obj the object to extract the {@code byte} value
1.372 + * from
1.373 + * @return the value of the {@code byte} field
1.374 + *
1.375 + * @exception IllegalAccessException if this {@code Field} object
1.376 + * is enforcing Java language access control and the underlying
1.377 + * field is inaccessible.
1.378 + * @exception IllegalArgumentException if the specified object is not
1.379 + * an instance of the class or interface declaring the
1.380 + * underlying field (or a subclass or implementor
1.381 + * thereof), or if the field value cannot be
1.382 + * converted to the type {@code byte} by a
1.383 + * widening conversion.
1.384 + * @exception NullPointerException if the specified object is null
1.385 + * and the field is an instance field.
1.386 + * @exception ExceptionInInitializerError if the initialization provoked
1.387 + * by this method fails.
1.388 + * @see Field#get
1.389 + */
1.390 + public byte getByte(Object obj)
1.391 + throws IllegalArgumentException, IllegalAccessException
1.392 + {
1.393 + return getFieldAccessor(obj).getByte(obj);
1.394 + }
1.395 +
1.396 + /**
1.397 + * Gets the value of a static or instance field of type
1.398 + * {@code char} or of another primitive type convertible to
1.399 + * type {@code char} via a widening conversion.
1.400 + *
1.401 + * @param obj the object to extract the {@code char} value
1.402 + * from
1.403 + * @return the value of the field converted to type {@code char}
1.404 + *
1.405 + * @exception IllegalAccessException if this {@code Field} object
1.406 + * is enforcing Java language access control and the underlying
1.407 + * field is inaccessible.
1.408 + * @exception IllegalArgumentException if the specified object is not
1.409 + * an instance of the class or interface declaring the
1.410 + * underlying field (or a subclass or implementor
1.411 + * thereof), or if the field value cannot be
1.412 + * converted to the type {@code char} by a
1.413 + * widening conversion.
1.414 + * @exception NullPointerException if the specified object is null
1.415 + * and the field is an instance field.
1.416 + * @exception ExceptionInInitializerError if the initialization provoked
1.417 + * by this method fails.
1.418 + * @see Field#get
1.419 + */
1.420 + public char getChar(Object obj)
1.421 + throws IllegalArgumentException, IllegalAccessException
1.422 + {
1.423 + return getFieldAccessor(obj).getChar(obj);
1.424 + }
1.425 +
1.426 + /**
1.427 + * Gets the value of a static or instance field of type
1.428 + * {@code short} or of another primitive type convertible to
1.429 + * type {@code short} via a widening conversion.
1.430 + *
1.431 + * @param obj the object to extract the {@code short} value
1.432 + * from
1.433 + * @return the value of the field converted to type {@code short}
1.434 + *
1.435 + * @exception IllegalAccessException if this {@code Field} object
1.436 + * is enforcing Java language access control and the underlying
1.437 + * field is inaccessible.
1.438 + * @exception IllegalArgumentException if the specified object is not
1.439 + * an instance of the class or interface declaring the
1.440 + * underlying field (or a subclass or implementor
1.441 + * thereof), or if the field value cannot be
1.442 + * converted to the type {@code short} by a
1.443 + * widening conversion.
1.444 + * @exception NullPointerException if the specified object is null
1.445 + * and the field is an instance field.
1.446 + * @exception ExceptionInInitializerError if the initialization provoked
1.447 + * by this method fails.
1.448 + * @see Field#get
1.449 + */
1.450 + public short getShort(Object obj)
1.451 + throws IllegalArgumentException, IllegalAccessException
1.452 + {
1.453 + return getFieldAccessor(obj).getShort(obj);
1.454 + }
1.455 +
1.456 + /**
1.457 + * Gets the value of a static or instance field of type
1.458 + * {@code int} or of another primitive type convertible to
1.459 + * type {@code int} via a widening conversion.
1.460 + *
1.461 + * @param obj the object to extract the {@code int} value
1.462 + * from
1.463 + * @return the value of the field converted to type {@code int}
1.464 + *
1.465 + * @exception IllegalAccessException if this {@code Field} object
1.466 + * is enforcing Java language access control and the underlying
1.467 + * field is inaccessible.
1.468 + * @exception IllegalArgumentException if the specified object is not
1.469 + * an instance of the class or interface declaring the
1.470 + * underlying field (or a subclass or implementor
1.471 + * thereof), or if the field value cannot be
1.472 + * converted to the type {@code int} by a
1.473 + * widening conversion.
1.474 + * @exception NullPointerException if the specified object is null
1.475 + * and the field is an instance field.
1.476 + * @exception ExceptionInInitializerError if the initialization provoked
1.477 + * by this method fails.
1.478 + * @see Field#get
1.479 + */
1.480 + public int getInt(Object obj)
1.481 + throws IllegalArgumentException, IllegalAccessException
1.482 + {
1.483 + return getFieldAccessor(obj).getInt(obj);
1.484 + }
1.485 +
1.486 + /**
1.487 + * Gets the value of a static or instance field of type
1.488 + * {@code long} or of another primitive type convertible to
1.489 + * type {@code long} via a widening conversion.
1.490 + *
1.491 + * @param obj the object to extract the {@code long} value
1.492 + * from
1.493 + * @return the value of the field converted to type {@code long}
1.494 + *
1.495 + * @exception IllegalAccessException if this {@code Field} object
1.496 + * is enforcing Java language access control and the underlying
1.497 + * field is inaccessible.
1.498 + * @exception IllegalArgumentException if the specified object is not
1.499 + * an instance of the class or interface declaring the
1.500 + * underlying field (or a subclass or implementor
1.501 + * thereof), or if the field value cannot be
1.502 + * converted to the type {@code long} by a
1.503 + * widening conversion.
1.504 + * @exception NullPointerException if the specified object is null
1.505 + * and the field is an instance field.
1.506 + * @exception ExceptionInInitializerError if the initialization provoked
1.507 + * by this method fails.
1.508 + * @see Field#get
1.509 + */
1.510 + public long getLong(Object obj)
1.511 + throws IllegalArgumentException, IllegalAccessException
1.512 + {
1.513 + return getFieldAccessor(obj).getLong(obj);
1.514 + }
1.515 +
1.516 + /**
1.517 + * Gets the value of a static or instance field of type
1.518 + * {@code float} or of another primitive type convertible to
1.519 + * type {@code float} via a widening conversion.
1.520 + *
1.521 + * @param obj the object to extract the {@code float} value
1.522 + * from
1.523 + * @return the value of the field converted to type {@code float}
1.524 + *
1.525 + * @exception IllegalAccessException if this {@code Field} object
1.526 + * is enforcing Java language access control and the underlying
1.527 + * field is inaccessible.
1.528 + * @exception IllegalArgumentException if the specified object is not
1.529 + * an instance of the class or interface declaring the
1.530 + * underlying field (or a subclass or implementor
1.531 + * thereof), or if the field value cannot be
1.532 + * converted to the type {@code float} by a
1.533 + * widening conversion.
1.534 + * @exception NullPointerException if the specified object is null
1.535 + * and the field is an instance field.
1.536 + * @exception ExceptionInInitializerError if the initialization provoked
1.537 + * by this method fails.
1.538 + * @see Field#get
1.539 + */
1.540 + public float getFloat(Object obj)
1.541 + throws IllegalArgumentException, IllegalAccessException
1.542 + {
1.543 + return getFieldAccessor(obj).getFloat(obj);
1.544 + }
1.545 +
1.546 + /**
1.547 + * Gets the value of a static or instance field of type
1.548 + * {@code double} or of another primitive type convertible to
1.549 + * type {@code double} via a widening conversion.
1.550 + *
1.551 + * @param obj the object to extract the {@code double} value
1.552 + * from
1.553 + * @return the value of the field converted to type {@code double}
1.554 + *
1.555 + * @exception IllegalAccessException if this {@code Field} object
1.556 + * is enforcing Java language access control and the underlying
1.557 + * field is inaccessible.
1.558 + * @exception IllegalArgumentException if the specified object is not
1.559 + * an instance of the class or interface declaring the
1.560 + * underlying field (or a subclass or implementor
1.561 + * thereof), or if the field value cannot be
1.562 + * converted to the type {@code double} by a
1.563 + * widening conversion.
1.564 + * @exception NullPointerException if the specified object is null
1.565 + * and the field is an instance field.
1.566 + * @exception ExceptionInInitializerError if the initialization provoked
1.567 + * by this method fails.
1.568 + * @see Field#get
1.569 + */
1.570 + public double getDouble(Object obj)
1.571 + throws IllegalArgumentException, IllegalAccessException
1.572 + {
1.573 + return getFieldAccessor(obj).getDouble(obj);
1.574 + }
1.575 +
1.576 + /**
1.577 + * Sets the field represented by this {@code Field} object on the
1.578 + * specified object argument to the specified new value. The new
1.579 + * value is automatically unwrapped if the underlying field has a
1.580 + * primitive type.
1.581 + *
1.582 + * <p>The operation proceeds as follows:
1.583 + *
1.584 + * <p>If the underlying field is static, the {@code obj} argument is
1.585 + * ignored; it may be null.
1.586 + *
1.587 + * <p>Otherwise the underlying field is an instance field. If the
1.588 + * specified object argument is null, the method throws a
1.589 + * {@code NullPointerException}. If the specified object argument is not
1.590 + * an instance of the class or interface declaring the underlying
1.591 + * field, the method throws an {@code IllegalArgumentException}.
1.592 + *
1.593 + * <p>If this {@code Field} object is enforcing Java language access control, and
1.594 + * the underlying field is inaccessible, the method throws an
1.595 + * {@code IllegalAccessException}.
1.596 + *
1.597 + * <p>If the underlying field is final, the method throws an
1.598 + * {@code IllegalAccessException} unless {@code setAccessible(true)}
1.599 + * has succeeded for this {@code Field} object
1.600 + * and the field is non-static. Setting a final field in this way
1.601 + * is meaningful only during deserialization or reconstruction of
1.602 + * instances of classes with blank final fields, before they are
1.603 + * made available for access by other parts of a program. Use in
1.604 + * any other context may have unpredictable effects, including cases
1.605 + * in which other parts of a program continue to use the original
1.606 + * value of this field.
1.607 + *
1.608 + * <p>If the underlying field is of a primitive type, an unwrapping
1.609 + * conversion is attempted to convert the new value to a value of
1.610 + * a primitive type. If this attempt fails, the method throws an
1.611 + * {@code IllegalArgumentException}.
1.612 + *
1.613 + * <p>If, after possible unwrapping, the new value cannot be
1.614 + * converted to the type of the underlying field by an identity or
1.615 + * widening conversion, the method throws an
1.616 + * {@code IllegalArgumentException}.
1.617 + *
1.618 + * <p>If the underlying field is static, the class that declared the
1.619 + * field is initialized if it has not already been initialized.
1.620 + *
1.621 + * <p>The field is set to the possibly unwrapped and widened new value.
1.622 + *
1.623 + * <p>If the field is hidden in the type of {@code obj},
1.624 + * the field's value is set according to the preceding rules.
1.625 + *
1.626 + * @param obj the object whose field should be modified
1.627 + * @param value the new value for the field of {@code obj}
1.628 + * being modified
1.629 + *
1.630 + * @exception IllegalAccessException if this {@code Field} object
1.631 + * is enforcing Java language access control and the underlying
1.632 + * field is either inaccessible or final.
1.633 + * @exception IllegalArgumentException if the specified object is not an
1.634 + * instance of the class or interface declaring the underlying
1.635 + * field (or a subclass or implementor thereof),
1.636 + * or if an unwrapping conversion fails.
1.637 + * @exception NullPointerException if the specified object is null
1.638 + * and the field is an instance field.
1.639 + * @exception ExceptionInInitializerError if the initialization provoked
1.640 + * by this method fails.
1.641 + */
1.642 + public void set(Object obj, Object value)
1.643 + throws IllegalArgumentException, IllegalAccessException
1.644 + {
1.645 + getFieldAccessor(obj).set(obj, value);
1.646 + }
1.647 +
1.648 + /**
1.649 + * Sets the value of a field as a {@code boolean} on the specified object.
1.650 + * This method is equivalent to
1.651 + * {@code set(obj, zObj)},
1.652 + * where {@code zObj} is a {@code Boolean} object and
1.653 + * {@code zObj.booleanValue() == z}.
1.654 + *
1.655 + * @param obj the object whose field should be modified
1.656 + * @param z the new value for the field of {@code obj}
1.657 + * being modified
1.658 + *
1.659 + * @exception IllegalAccessException if this {@code Field} object
1.660 + * is enforcing Java language access control and the underlying
1.661 + * field is either inaccessible or final.
1.662 + * @exception IllegalArgumentException if the specified object is not an
1.663 + * instance of the class or interface declaring the underlying
1.664 + * field (or a subclass or implementor thereof),
1.665 + * or if an unwrapping conversion fails.
1.666 + * @exception NullPointerException if the specified object is null
1.667 + * and the field is an instance field.
1.668 + * @exception ExceptionInInitializerError if the initialization provoked
1.669 + * by this method fails.
1.670 + * @see Field#set
1.671 + */
1.672 + public void setBoolean(Object obj, boolean z)
1.673 + throws IllegalArgumentException, IllegalAccessException
1.674 + {
1.675 + getFieldAccessor(obj).setBoolean(obj, z);
1.676 + }
1.677 +
1.678 + /**
1.679 + * Sets the value of a field as a {@code byte} on the specified object.
1.680 + * This method is equivalent to
1.681 + * {@code set(obj, bObj)},
1.682 + * where {@code bObj} is a {@code Byte} object and
1.683 + * {@code bObj.byteValue() == b}.
1.684 + *
1.685 + * @param obj the object whose field should be modified
1.686 + * @param b the new value for the field of {@code obj}
1.687 + * being modified
1.688 + *
1.689 + * @exception IllegalAccessException if this {@code Field} object
1.690 + * is enforcing Java language access control and the underlying
1.691 + * field is either inaccessible or final.
1.692 + * @exception IllegalArgumentException if the specified object is not an
1.693 + * instance of the class or interface declaring the underlying
1.694 + * field (or a subclass or implementor thereof),
1.695 + * or if an unwrapping conversion fails.
1.696 + * @exception NullPointerException if the specified object is null
1.697 + * and the field is an instance field.
1.698 + * @exception ExceptionInInitializerError if the initialization provoked
1.699 + * by this method fails.
1.700 + * @see Field#set
1.701 + */
1.702 + public void setByte(Object obj, byte b)
1.703 + throws IllegalArgumentException, IllegalAccessException
1.704 + {
1.705 + getFieldAccessor(obj).setByte(obj, b);
1.706 + }
1.707 +
1.708 + /**
1.709 + * Sets the value of a field as a {@code char} on the specified object.
1.710 + * This method is equivalent to
1.711 + * {@code set(obj, cObj)},
1.712 + * where {@code cObj} is a {@code Character} object and
1.713 + * {@code cObj.charValue() == c}.
1.714 + *
1.715 + * @param obj the object whose field should be modified
1.716 + * @param c the new value for the field of {@code obj}
1.717 + * being modified
1.718 + *
1.719 + * @exception IllegalAccessException if this {@code Field} object
1.720 + * is enforcing Java language access control and the underlying
1.721 + * field is either inaccessible or final.
1.722 + * @exception IllegalArgumentException if the specified object is not an
1.723 + * instance of the class or interface declaring the underlying
1.724 + * field (or a subclass or implementor thereof),
1.725 + * or if an unwrapping conversion fails.
1.726 + * @exception NullPointerException if the specified object is null
1.727 + * and the field is an instance field.
1.728 + * @exception ExceptionInInitializerError if the initialization provoked
1.729 + * by this method fails.
1.730 + * @see Field#set
1.731 + */
1.732 + public void setChar(Object obj, char c)
1.733 + throws IllegalArgumentException, IllegalAccessException
1.734 + {
1.735 + getFieldAccessor(obj).setChar(obj, c);
1.736 + }
1.737 +
1.738 + /**
1.739 + * Sets the value of a field as a {@code short} on the specified object.
1.740 + * This method is equivalent to
1.741 + * {@code set(obj, sObj)},
1.742 + * where {@code sObj} is a {@code Short} object and
1.743 + * {@code sObj.shortValue() == s}.
1.744 + *
1.745 + * @param obj the object whose field should be modified
1.746 + * @param s the new value for the field of {@code obj}
1.747 + * being modified
1.748 + *
1.749 + * @exception IllegalAccessException if this {@code Field} object
1.750 + * is enforcing Java language access control and the underlying
1.751 + * field is either inaccessible or final.
1.752 + * @exception IllegalArgumentException if the specified object is not an
1.753 + * instance of the class or interface declaring the underlying
1.754 + * field (or a subclass or implementor thereof),
1.755 + * or if an unwrapping conversion fails.
1.756 + * @exception NullPointerException if the specified object is null
1.757 + * and the field is an instance field.
1.758 + * @exception ExceptionInInitializerError if the initialization provoked
1.759 + * by this method fails.
1.760 + * @see Field#set
1.761 + */
1.762 + public void setShort(Object obj, short s)
1.763 + throws IllegalArgumentException, IllegalAccessException
1.764 + {
1.765 + getFieldAccessor(obj).setShort(obj, s);
1.766 + }
1.767 +
1.768 + /**
1.769 + * Sets the value of a field as an {@code int} on the specified object.
1.770 + * This method is equivalent to
1.771 + * {@code set(obj, iObj)},
1.772 + * where {@code iObj} is a {@code Integer} object and
1.773 + * {@code iObj.intValue() == i}.
1.774 + *
1.775 + * @param obj the object whose field should be modified
1.776 + * @param i the new value for the field of {@code obj}
1.777 + * being modified
1.778 + *
1.779 + * @exception IllegalAccessException if this {@code Field} object
1.780 + * is enforcing Java language access control and the underlying
1.781 + * field is either inaccessible or final.
1.782 + * @exception IllegalArgumentException if the specified object is not an
1.783 + * instance of the class or interface declaring the underlying
1.784 + * field (or a subclass or implementor thereof),
1.785 + * or if an unwrapping conversion fails.
1.786 + * @exception NullPointerException if the specified object is null
1.787 + * and the field is an instance field.
1.788 + * @exception ExceptionInInitializerError if the initialization provoked
1.789 + * by this method fails.
1.790 + * @see Field#set
1.791 + */
1.792 + public void setInt(Object obj, int i)
1.793 + throws IllegalArgumentException, IllegalAccessException
1.794 + {
1.795 + getFieldAccessor(obj).setInt(obj, i);
1.796 + }
1.797 +
1.798 + /**
1.799 + * Sets the value of a field as a {@code long} on the specified object.
1.800 + * This method is equivalent to
1.801 + * {@code set(obj, lObj)},
1.802 + * where {@code lObj} is a {@code Long} object and
1.803 + * {@code lObj.longValue() == l}.
1.804 + *
1.805 + * @param obj the object whose field should be modified
1.806 + * @param l the new value for the field of {@code obj}
1.807 + * being modified
1.808 + *
1.809 + * @exception IllegalAccessException if this {@code Field} object
1.810 + * is enforcing Java language access control and the underlying
1.811 + * field is either inaccessible or final.
1.812 + * @exception IllegalArgumentException if the specified object is not an
1.813 + * instance of the class or interface declaring the underlying
1.814 + * field (or a subclass or implementor thereof),
1.815 + * or if an unwrapping conversion fails.
1.816 + * @exception NullPointerException if the specified object is null
1.817 + * and the field is an instance field.
1.818 + * @exception ExceptionInInitializerError if the initialization provoked
1.819 + * by this method fails.
1.820 + * @see Field#set
1.821 + */
1.822 + public void setLong(Object obj, long l)
1.823 + throws IllegalArgumentException, IllegalAccessException
1.824 + {
1.825 + getFieldAccessor(obj).setLong(obj, l);
1.826 + }
1.827 +
1.828 + /**
1.829 + * Sets the value of a field as a {@code float} on the specified object.
1.830 + * This method is equivalent to
1.831 + * {@code set(obj, fObj)},
1.832 + * where {@code fObj} is a {@code Float} object and
1.833 + * {@code fObj.floatValue() == f}.
1.834 + *
1.835 + * @param obj the object whose field should be modified
1.836 + * @param f the new value for the field of {@code obj}
1.837 + * being modified
1.838 + *
1.839 + * @exception IllegalAccessException if this {@code Field} object
1.840 + * is enforcing Java language access control and the underlying
1.841 + * field is either inaccessible or final.
1.842 + * @exception IllegalArgumentException if the specified object is not an
1.843 + * instance of the class or interface declaring the underlying
1.844 + * field (or a subclass or implementor thereof),
1.845 + * or if an unwrapping conversion fails.
1.846 + * @exception NullPointerException if the specified object is null
1.847 + * and the field is an instance field.
1.848 + * @exception ExceptionInInitializerError if the initialization provoked
1.849 + * by this method fails.
1.850 + * @see Field#set
1.851 + */
1.852 + public void setFloat(Object obj, float f)
1.853 + throws IllegalArgumentException, IllegalAccessException
1.854 + {
1.855 + getFieldAccessor(obj).setFloat(obj, f);
1.856 + }
1.857 +
1.858 + /**
1.859 + * Sets the value of a field as a {@code double} on the specified object.
1.860 + * This method is equivalent to
1.861 + * {@code set(obj, dObj)},
1.862 + * where {@code dObj} is a {@code Double} object and
1.863 + * {@code dObj.doubleValue() == d}.
1.864 + *
1.865 + * @param obj the object whose field should be modified
1.866 + * @param d the new value for the field of {@code obj}
1.867 + * being modified
1.868 + *
1.869 + * @exception IllegalAccessException if this {@code Field} object
1.870 + * is enforcing Java language access control and the underlying
1.871 + * field is either inaccessible or final.
1.872 + * @exception IllegalArgumentException if the specified object is not an
1.873 + * instance of the class or interface declaring the underlying
1.874 + * field (or a subclass or implementor thereof),
1.875 + * or if an unwrapping conversion fails.
1.876 + * @exception NullPointerException if the specified object is null
1.877 + * and the field is an instance field.
1.878 + * @exception ExceptionInInitializerError if the initialization provoked
1.879 + * by this method fails.
1.880 + * @see Field#set
1.881 + */
1.882 + public void setDouble(Object obj, double d)
1.883 + throws IllegalArgumentException, IllegalAccessException
1.884 + {
1.885 + getFieldAccessor(obj).setDouble(obj, d);
1.886 + }
1.887 +
1.888 + // Convenience routine which performs security checks
1.889 + private FieldAccessor getFieldAccessor(Object obj)
1.890 + throws IllegalAccessException
1.891 + {
1.892 + throw new SecurityException();
1.893 + }
1.894 +
1.895 + private static abstract class FieldAccessor {
1.896 + abstract void setShort(Object obj, short s);
1.897 + abstract void setInt(Object obj, int i);
1.898 + abstract void setChar(Object obj, char c);
1.899 + abstract void setByte(Object obj, byte b);
1.900 + abstract void setBoolean(Object obj, boolean z);
1.901 + abstract void set(Object obj, Object value);
1.902 + abstract double getDouble(Object obj);
1.903 + abstract void setLong(Object obj, long l);
1.904 + abstract void setFloat(Object obj, float f);
1.905 + abstract void setDouble(Object obj, double d);
1.906 + abstract long getLong(Object obj);
1.907 + abstract int getInt(Object obj);
1.908 + abstract short getShort(Object obj);
1.909 + abstract char getChar(Object obj);
1.910 + abstract byte getByte(Object obj);
1.911 + abstract boolean getBoolean(Object obj);
1.912 + abstract Object get(Object obj);
1.913 + abstract float getFloat(Object obj);
1.914 + }
1.915 +
1.916 + /*
1.917 + * Utility routine to paper over array type names
1.918 + */
1.919 + static String getTypeName(Class<?> type) {
1.920 + if (type.isArray()) {
1.921 + try {
1.922 + Class<?> cl = type;
1.923 + int dimensions = 0;
1.924 + while (cl.isArray()) {
1.925 + dimensions++;
1.926 + cl = cl.getComponentType();
1.927 + }
1.928 + StringBuffer sb = new StringBuffer();
1.929 + sb.append(cl.getName());
1.930 + for (int i = 0; i < dimensions; i++) {
1.931 + sb.append("[]");
1.932 + }
1.933 + return sb.toString();
1.934 + } catch (Throwable e) { /*FALLTHRU*/ }
1.935 + }
1.936 + return type.getName();
1.937 + }
1.938 +
1.939 + /**
1.940 + * @throws NullPointerException {@inheritDoc}
1.941 + * @since 1.5
1.942 + */
1.943 + public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
1.944 + if (annotationClass == null)
1.945 + throw new NullPointerException();
1.946 +
1.947 + throw new UnsupportedOperationException();
1.948 + }
1.949 +
1.950 + /**
1.951 + * @since 1.5
1.952 + */
1.953 + public Annotation[] getDeclaredAnnotations() {
1.954 + throw new UnsupportedOperationException();
1.955 + }
1.956 +}