Java dize gerçekten değişmez mi?
Hepimiz String Java değişmez ama aşağıdaki kodu kontrol edin.
String s1 = "Hello World";
String s2 = "Hello World";
String s3 = s1.substring(6);
System.out.println(s1); // Hello World
System.out.println(s2); // Hello World
System.out.println(s3); // World
Field field = String.class.getDeclaredField("value");
field.setAccessible(true);
char[] value = (char[])field.get(s1);
value[6] = 'J';
value[7] = 'a';
value[8] = 'v';
value[9] = 'a';
value[10] = '!';
System.out.println(s1); // Hello Java!
System.out.println(s2); // Hello Java!
System.out.println(s3); // World
Niye bu program bu şekilde çalışır? Ve neden s1 s2 değeri, ancak s3 değiştirilmedi?
CEVAP
String değişmez* ancak kamu API kullanarak değiştiremezsiniz Bu sadece anlamına gelir.
Burada ne yaptığını normal API, yansıma kullanarak engellemeyi. Aynı şekilde, çeteleler değerleri değiştirebilirsiniz, arama tablosu Tamsayı vb autoboxing kullanılan değiştirin.
Şimdi, s1 s2 değeri değiştir sebebi, ikisi de aynı staj dize bakın. Derleyici bu canlılar tarafından belirtildiği gibi).
Nedeni s3 yapardeğilvalue dizi (Java 7u6 önceit did in earlier version of Java,) paylaşım olacağını düşündüm. aslında bana biraz şaşırtıcı oldu. Ancak, String, biz kaynak kodu bakarak bir dize için value karakter dizisi aslında (Arrays.copyOfRange(..)) kullanarak kopyalanan görebilir. Bu değişmeden gidiyor nedeni budur.
Böyle şeyler yapmak için SecurityManager, önlemek için kötü amaçlı kod yükleyebilir. Ama bazı kütüphaneler yansıma hileler bu tür kullanarak bağlı olduğunu göz önünde tutmak (genellikle ORM araçları OLANLAR kütüphaneleri gibi).
*) Ben başlangıçta Strings gerçekten değişmez, sadece olmadığını yazdı "değişmez". etkili Bu value dizi gerçekten private final işaretli olduğu String, geçerli uygulama yanıltıcı olabilir. Hala dikkati çekiyor, ama orada hiçbir şekilde beyan bir dizi Java olarak değişmez, yani sağlık için değil, maruz dışında kendi sınıfı ile uygun erişim değiştiricileri.
Bu konu gibi ezici bir çoğunlukla popüler, İşte bazı önerilen ek okuma: Heinz Kabutz's Reflection Madness talk JavaZone 2009, kapakları bir çok konularda OP ile birlikte diğer yansıması... delilik.
Bu bazen yararlıdır neden kapsar. Ve çoğu zaman neden, bunu önlemek. :-)

Neden char[] şifreler için Dize Java t...
Java ile bir numaralama için bir Dize ...
Nasıl bir dosyanın içeriğini bir Java ...
Java nasıl bir dize bölmek...
Olabilirdi vs Dize birleÅŸtirme StringB...