Строка имеет приватный финал char[]
.когда создается новый объект String, массив также создается и заполняется.к нему нельзя получить доступ позже [извне] или изменить [на самом деле это можно сделать с помощью отражения, но мы оставим это в стороне].
это «неизменяемый», поскольку после создания строки ее значение не можетПри изменении строки «корова» всегда будет иметь значение «корова».
Мы не видим измененную строку, поскольку она неизменна, один и тот же объект никогда не будет изменен, независимо от того, что вы с ним делаете[помимо изменения с отражением].поэтому "корова" + "лошадь" создадут новый объект String и НЕ изменят последний объект.
, если вы определите:
void foo(String arg) {
arg= arg + " horse";
}
и вы вызовете:
String str = "cow";
foo(str);
str
, где вызов не изменен [поскольку это исходная ссылка на тот же объект!] Когда вы изменили arg
, вы просто изменили его, чтобы ссылаться на другой объект Stringи НЕ изменил фактический исходный объект.поэтому str
будет тем же объектом, который не был изменен, все еще содержащий "cow"
, если вы все еще хотите изменить объект String, вы можете сделать это с отражением.Однако, это без консультации и может иметь некоторые серьезные побочные эффекты:
String str = "cow";
try {
Field value = str.getClass().getDeclaredField("value");
Field count = str.getClass().getDeclaredField("count");
Field hash = str.getClass().getDeclaredField("hash");
Field offset = str.getClass().getDeclaredField("offset");
value.setAccessible(true);
count.setAccessible(true);
hash.setAccessible(true);
offset.setAccessible(true);
char[] newVal = { 'c','o','w',' ','h','o','r','s','e' };
value.set(str,newVal);
count.set(str,newVal.length);
hash.set(str,0);
offset.set(str,0);
} catch (NoSuchFieldException e) {
} catch (IllegalAccessException e) {}
System.out.println(str);
}