THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

public static void
setShortField(Object o, String name, short nv)
throws NoSuchFieldException, IllegalAccessException
{
Field field = o.getClass().getField(name);
field.set(o, nv);
}


Although set takes an Object parameter, we can pass a short directly and let a boxing conversion wrap it
in a Short object.


If the field of the specified object is not accessible and access control is being enforced, an
IllegalAccessException is thrown. If the passed object does not have a type that declares the
underlying field, an IllegalArgumentException is thrown. If the field is non-static and the passed
object reference is null, a NullPointerException is thrown. Accessing a static field can require
initializing a class, so it is also possible for an ExceptionInInitializerError to be thrown.


The Field class also has specific methods for getting and setting primitive types. You can invoke
getPrimitiveType and setPrimitiveType on a Field object, where PrimitiveType is the
primitive type name (with an initial uppercase letter). The get example just shown could have used the
statement


short value = field.getShort(o);


The set example could have used


field.setShort(o, nv);


and avoided the use of the wrapper object.


Field implements AnnotatedElement, and the annotations on a field can be queried as discussed in
Section 16.2 on page 414.


With some work you can use a Field object as a way to manipulate an arbitrary value, but you should avoid
this when possible. The language is designed to catch as many programming errors as possible when the
program is compiled. The less you write using indirections such as the Field object, the more your errors
will be prevented before they are compiled into code. Also, as you can see, it takes more reading to see what
is happening in the preceding code compared with what it would take if the name of the field were simply
used in the normal syntax.


16.6.1. Final Fields


Under normal circumstances attempting to set the value of a field declared as final will result in
IllegalAccessException being thrown. This is what you would expect: Final fields should never have
their value changed. There are special circumstancessuch as during custom deserialization (see page
554)where it makes sense to change the value of a final field. You can do this via reflection only on instance
fields, and only if setAccessible(true) has been invoked on the Field object. Note that it is not
enough that setAccessible(true) would succeed, it must actually be called.

Free download pdf