Apropos a discussion of the non-final-ness of final fields, a colleague came up with this gem. What does the following code do?
// By Jed Wesley-Smith
public String getAString() {
//get a reference to the private field
//value in String class.
java.lang.reflect.Field stringValue =
String.class.getDeclaredField("value");
//make it accessible
stringValue.setAccessible(true);
//unsuspecting string
String sittingDuck = "sittingDuck!!!!!";
//black magic happening here
stringValue.set(sittingDuck,
"hastaLaVistaBaby".toCharArray());
//guess the output of this!
return "sittingDuck!!!!!";
}
Clarification: the value
field in String isn't actually final, if it were final we wouldn't be able to change the string's value from outside the String class. The thing about final fields not really being final was a catalyst for this code, but wasn't used in it. (Regarding final fields, the JVM only prevents the changing of a final field from outside a class. Technically, a class can change its own final field at any time, and is only prevented from doing so by the compiler. So you can get around the finality of final fields using bytecode manipulation.)
Prior art: Java Specialists' Newsletter: Insane Strings
Correction of Clarification You could still pull an equivalent trick if the value field were final: it's an array, so even if the field were final, the contents of the array would be wide open.