The Java virtual machine enforces the rules for object, field, method,
and constructor access. It prevents code from inappropriately accessing
or modifying private fields, for example. Access control is necessary
for object encapsulation (a key characteristic of object-oriented
programming languages) and fundamental for security (untrusted code must
not have access to critical system classes and class members).
Reflection (also called introspection) allows Java applications to
access and manipulate fields, methods, and constructors as first class
objects. An instance of the Method class, which corresponds to a method
of a class, may be treated just like any other object, and when the time
is right it may be invoked. Reflective access obeys the same access
rules described above -- most of the time.
Once in a while it's necessary to break the rules. Debuggers,
persistence mechanisms, and graphical application assembly tools need
access to all of the fields, methods, and constructors of a class. The
AccessibleObject class, the common superclass of the Field, Method, and
Constructor classes, provides a method to turn off the normal
accessibility checks. Access through an instance of the appropriate
class can occur unhindered.
This method, setAccessible(), is subject to normal permission checks if
a security manager is installed -- this provision prevents untrusted
code from using this mechanism to gain access to fields, methods, and
constructors that it ordinarily could not gain access to. The method
also throws an exception if an attempt is made to change the
accessibility of the constructor for the Class class.
Why the last restriction, you ask? An instance of the Class class is the
Java language level representation of a class's loaded byte-code. In
addition to the semantic ambiguity introduced by the presence of an
instance of the Class class without the associated byte-code, the
presence of such a class could be used to subvert other parts of the
Java security infrastructure.