Re: Why is String immutable?
"Chris Smith" <cdsmith@twu.net> wrote in message
The getfield opcode is checked by the bytecode verifier when the class
is loaded. If it tries to access a field to which it doesn't have
access permission, the verifier will throw a java.lang.VerifyError, and
the class will fail to load.
The picture is more complicated than that. For a start, I don't think that
it's the verifier's job to enforce access checks -- they shouldn't fail until
an illegal access is actually executed.
Secondly, the rules for when the JVM will actually enforce access seem to be
somewhat obscure. I know that it will /sometimes/ do checks, but not always.
And what "sometimes" means has changed over the years.
For instance. With JDK 1.5.0_06, compile these two files
========== A.java =================
public class A
{
// NB: deliberately public, despite the name
public String privateField = "Ooops!";
}
=========== B.java ================
public class B
{
public static void
main(String[] args)
{
A a = new A();
System.out.println("OK, here we go...");
System.out.println(a.privateField);
}
}
=================================
Then change the declaration of A.privateField to private, and recompile only
A.java. (All this messing around is just a way to generate bytecode containing
an "illegal" read -- people with convenient access to bytecode generation will
have more straightforward ways of doing it).
Then execute:
java -cp . B
and it prints:
OK, here we go...
Ooops!
OTOH, running java with the "future" argument:
java -Xfuture -cp . B
and it prints:
OK, here we go...
Exception in thread "main" java.lang.IllegalAccessError: tried to access
field A.privateField from class B
at B.main(B.java:8)
On the third hand, even without the -Xfuture argument, the current JVM will
(iirc) stop you accessing the internal fields of a String object. I'm not sure
on what basis it determines that some accesses should be checked and others
not.
As far as I know, /all/ such access should result in the JVM throwing runtime
exceptions, but Sun's JVM's seem to interpret that aspect of the spec a little
loosely...
(And anyway, there's always JNI ;-)
-- chris