czwartek, marca 06, 2008

Sekrety klasy String ;-)

String jest w Java'ie niemutowalny.
Mówiąc inaczej, jeżeli mamy już referencję do obiektu typu String stworzoną w taki np. sposób:

String str = "To jest test";

to już nigdy nie zmienimy zawartości tego obiektu.......

Podobno ;-)

Ktoś może spróbować takiego rozwiązania:
public void modificator(String str) {
str = "toster";
}
[...]
String str = "To jest test";
System.out.println(str); // TUTAJ wypisze się "To jest test"
modificator(str);
System.out.println(str); // A tutaj, też ;-)

Jak należało się spodziewać, takie rozwiązanie nie działa.

Ale co w momencie gdy zmienimy metodę modificator w taką jak poniżej? ;-)
public void modificator(String str) throws Exception {  
Field valueField = str.getClass().getDeclaredField("value");
valueField.setAccessible(true);
char[] value = (char[])valueField.get(str);
char[] reversed = new char[value.length];
for (int idx=0; idx<value.length; idx++) {
reversed[idx]=value[value.length-idx-1];
}
for (int idx=0; idx<value.length; idx++) {
value[idx]=reversed[idx];
}
}

Nagle okaże się, że String nie jest taki niezmienialny ;-) Nagle drugie wypisanie ujawni nam, że nasz obiekt się zmienił!

Na SCJP dobrze wiedzieć, że String jest niemutowalny, ale warto też pamiętać, że jak się ktoś uprze to jednak można go zmienić ;-)

Jeżeli przed wywołaniem metody modificator(String) stworzymy na podstawie naszego bazowego String'a łańcuch przy pomocy metody substring(int) to po przekazaniu naszego bazowego obiektu do modificator zmieni się także wygląd tego nowego obiektu.

Wszystko to prawda dla Sun Java, na innych może się okazać, że taki kod w ogóle nie zadziała :-) Dlatego ostrożnie należy podchodzić do takich "metod", trzeba też pamiętać, że String z jakichś powodów zdecydowano się zrobić niemutowalnym.

[sam na pomysł takiego potraktowania String'a nie wpadłem, kolega mi ten pomysł podsunął :-)]


Podobne postybeta
localStorage odsłona 2 - zaczynają się kłopoty ;-)
Ile to jest 1+1 w Java'ie?
JNI i łańcuchy ;-)
Potfór ;-) czyli generator z yield w Java'ie
Umiejętność programowania pomaga :-)