2013-07-26 2 views
4

У меня есть этот код
Строка пулы после изменения строки

String a="test"; 
String b="test"; 
if(a==b) 
    System.out.println("a == b"); 
else 
    System.out.println("Not True"); 

И каждый эксперты Java знает, что здесь if(a==b) будет принят из-за String pooling facility.
Согласно Струнный Объединив
Each time your code creates a string literal, the JVM checks the string literal pool first. If the string already exists in the pool, a reference to the pooled instance is returned. If the string does not exist in the pool, a new String object is created and placed in the pool. JVM keeps at most one object of any String in this pool. String literals always refer to an object in the string pool
и то, почему в коде выше прошло условие.
Теперь здесь возникает вопрос .В приведенном выше коде, когда я добавил две дополнительные линии a+="1" и b+="1" то теперь значения натянуть & б будет Test1.
Нового код будет как этого

String a="test"; 
    String b="test"; 
    if(a==b) 
     System.out.println("a == b"); 
    else 
     System.out.println("Not True"); 
     a+="1"; //it would be test1 now 
     b+="1"; //it would also be test1 now 
    if(a==b) 
     System.out.println("a == b"); 
    else 
     System.out.println("Not True"); 

Теперь после изменения строки, когда я поместил if(a==b) чек, то он не passed.I знает, что это происходит из-за неизменности особенности строки Но я хочу знать

1) После изменения, хранит ли JVM их два разных объекта?
2) Позволяет ли JVM звонить new String() для изменения любой строки?
3) Почему они не ссылаются ни на один, даже я пытался позвонить intern() во время изменения?
Q3 Подсказка:
a+="1".intern();
b+="1".intern();

+0

Домашнее задание предупреждение. –

+1

@ThomasW, если вы думаете об этом даже после такого подробного объяснения, я действительно хочу молиться за свои мысли. – Freak

ответ

1

1) Да, именно поэтому a == b не удается. Эти новые строки не являются частью пула строк, поскольку они не были литералами с самого начала.

2) Как указано в @LuiggiMendoza, он будет использовать конструктор String, если у компилятора есть способ узнать значения строк, иначе он скорее будет использовать StringBuilder внутренне (что в конце дня будет использовать конструктор String для возврата окончательной строки)

3) Даже если «1» является литералом, результат a + "1".intern(); сам по себе не является литералом, а новым объектом String, созданным с помощью конструктора String, поэтому он не добавляется в пул строк.

+0

Для пункта 2 это верно, только если значение 'String' может быть известно во время компиляции. –

+0

Спасибо @LuiggiMendoza, я отредактирую свой ответ, если вы не возражаете – morgano

+0

@LuiggiMendoza, и если он не был известен тогда? – Freak

1

Поскольку строки неизменяемы. После , изменяя строку, ваша переменная теперь будет ссылаться на другую String.

При создании new String JVM использует StringBuilder, если значения (-ы) не известны во время компиляции; в противном случае используется стандартный конструктор String.

При добавлении "1".intern(), то .intern() относится к "1" (неa + "1"); конкатенация производит новые объекты String (NOT), поэтому a и b не ссылаются на одни и те же объекты. Помните, когда Strings создаются с помощью оператора new, вы вынуждаете новую память выделяться.

Для того, чтобы a и b на самом деле ссылаться на тот же объект, вы должны вызвать .intern() на них обоих:

_a = _a.intern(); //adds _a to the String pool 
_b = _b.intern(); //makes _b point to the same object as _a, since _b.equals(_a) 
1

Это происходит потому, что, когда вы делаете «+ =», то это создает новый объект в куче не в String-пуле из-за непреложности String. Если вы хотите его в String pool, то снова вызовите intern() метод на обеих строках.

String a="test"; 
    String b="test"; 
    if(a==b) 
     System.out.println("a == b"); 
    else 
     System.out.println("Not True"); 
     a+="1"; //it would be test1 now 
     b+="1"; //it would also be test1 now 

     a=a.intern(); 
     b=b.intern(); 

    if(a==b) 
     System.out.println("a == b"); 
    else 
     System.out.println("Not True"); 

Теперь он произведет 'a == b' в обоих случаях. Для получения дополнительной информации о пуле строк, перейдите по этому адресу link.

Смежные вопросы