Как работают объекты String (например, неизменяемые объекты)? - PullRequest
1 голос
/ 04 марта 2010

У меня есть две ситуации:

String s = "aa";
s = s + " aa";
    System.out.println(s);
    //......

это отлично работает! Он печатает аа аа . Но есть проблема:

String s = "aa";
this.addStringToStatement(s, " aa");
System.out.println(s);
//...
private void addStringToStatement(String statement, Object value) {
    statement += value;
}

Он печатает: AA . Какова причина?? Спасибо!

Ответы [ 8 ]

5 голосов
/ 04 марта 2010

Здесь нужно понять две проблемы.

  1. Оператор добавления String создаст новый неизменный объект String. Выражение s + value является другим объектом в памяти от s.

  2. В вашей функции addStringToStatement при выполнении s tatement += value; вы не изменяете значение переменной s, скорее вы переназначаете локальный указатель statement на новый экземпляр String.

EDIT: исправлена ​​обычная ошибка noob: в Java передаются ссылки на объекты, а не сами объекты.

4 голосов
/ 04 марта 2010

Это потому, что в Java ссылка передается по значению. Вот когда вы передали s и «aa» как два параметра.

В переменной оператора метода (которая имеет ссылку на s) изменено , чтобы указывать на что-то еще, например, "aa aa". Обратите внимание, что передается только ссылка на оператор, s по-прежнему указывает на «aa».

Таким образом, когда вы печатаете s, вы получаете то, что ожидается:)

3 голосов
/ 04 марта 2010

это из-за того, как передача по значению работает в Java, вам нужно сделать что-то вроде этого:

String s = "aa";
s = this.addStringToStatement(s, " aa");
System.out.println(s);
//...
private string addStringToStatement(String statement, Object value) {
    statement += value;
    return statement;
}
1 голос
/ 05 марта 2010

@ Фрэнк Мейснер (новичок в этом, пока не может отвечать на ответы)

Просто чтобы прояснить разницу между String и StringBuilder (в случае, если кто-то читает это, запутался), в то время как оба сохраняют CharSequenceдержать как char [], char [] внутри String не может быть изменено, поэтому для каждого изменения должна быть создана новая String.В случае StringBuilder существуют методы, такие как StringBuilder.append (String), которые могут изменить внутренний char [] объекта StringBuilder, поэтому если вызывается StringBuilder.append (String), для объекта не нужно создавать новый объект.содержимое StringBuilder может быть изменено.

Согласно примеру Фрэнка Мейснера, System.out.println (sb);напечатает «aa aa», так как метод append (String) был вызван в StringBuilder sb.final здесь не больно, так как идентичность sb не меняется, только его состояние.

1 голос
/ 04 марта 2010

Строки в Java неизменны. Если у вас есть строка s = "aa", у вас есть только ссылка на строку "aa" внутри JVM. Если вы хотите, чтобы строка «aa aa» была присвоена s, вы должны назначить только s (aa aa) (еще одну строку внутри JVM) для s, aa скрывается где-то еще в JVM.

Утверждение «Java-ссылки передаются по значению» несколько сбивает с толку (если это правда). Если вы используете StringBuilder sb и передаете этот StringBuilder функции, ссылка «копируется», но все равно указывает на тот же объект, что и sb:

public static void main(String[] args) {
    final StringBuilder sb = new StringBuilder();
    f(sb);
    System.out.println(sb);
}

private static void f(final StringBuilder sb) {
    sb.append("aa aa");
}
1 голос
/ 04 марта 2010

Вы должны вернуть переменную «Statement».Без "this. *" Части.

String s = "aa";
s = addStringToStatement(s, " aa");
System.out.println(s);
//...
 private String addStringToStatement(String statement, Object value) {
    statement += value;
    return statement;
}
0 голосов
/ 04 марта 2010

Java ссылки передаются по значению. Когда вы передаете String методу, и он изменяется внутри, это указывает на другое String. Вы можете либо вернуть String после добавления, либо использовать StringBuffer в качестве аргумента.

0 голосов
/ 04 марта 2010

+ = в случае строки не изменяет саму строку, а создает новую строку. в случае вашего метода вы устанавливаете эту новую строковую ссылку на локальную переменную (параметр)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...