2015-07-16 5 views
1

В Java, когда мы пишемГде строковый литерал, который был принят в конструкторе сохраняется, когда мы создаем новый объект String,

String S1 = "TestString"; 
String S2 = "TestString"; 

, а затем сравнить с if(S1==S2), мы получаем истинное как логический результат. Объяснение тому же, что строковые константы создаются в пуле строк и, следовательно, это одна и та же строковая константа, которая здесь передается как S1, так и S2. Кроме того, если мы пишем что-то вроде

String S1 = new String("TestString"); 

String S2 = new String("TestString"); 

, а затем сделать сравнение с if(S1==S2), мы получаем ложные. Причина в том, что ссылки S1 и S2 различны, поскольку литералы строк создаются в куче.

Мой вопрос в том, где был строковый литерал «TestString», который был передан в созданном конструкторе? Является ли он таким же, как строковый литерал/константа? и, следовательно, должен быть создан в пуле, как это было в случае 1? если это тогда, когда мы пишем что-то вроде после двух вышеупомянутых заявлений

String S3 = "TestString"; 

это не должно создать новую строку буквальной и сравнение if(S1==S3) должно дать мне верно, но это дает ложь.

Так что я не могу понять, где и когда этот строковый литерал передается в создаваемом конструкторе.

Любая помощь была бы принята с благодарностью.

+0

== и str1.equals (str2) относятся к разным операторам/методам –

ответ

4

Мой вопрос в том, где был строковый литерал «TestString», который был передан в созданном конструкторе? Это то же самое, что и строковый литерал/константа? и, следовательно, должен быть создан в пуле, как это было в случае 1?

Правильно, постоянная строка передается вызов конструктора new String("TestString") хранится в строковом пуле, так же, как в заявлении String S1 = "TestString".

String S1 = new String("TestString"); 

String S2 = new String("TestString"); 

String S3 = "TestString"; 

В этом случае S1==S3 дает ложным, потому что S3 относится строка буквальной, которая была создана аргументом конструктора, используемым для S1, тогда как S1 это другая строка (так как он создается с помощью конструктора).

+0

Если вы откроете свой код в отладчике и посмотрите на 'S1.value' и' S2.value', вы увидите что-то вроде '[ C @ NNN', где NNN - это хэш-код массива символов, который представляет «TestString». Эти значения будут равны для S1 и S2, поддерживающие утверждение, что S1 и S2 используют одни и те же данные –

+0

@DavidSoroko, a) это деталь реализации b) это изменилось между версиями c) в openjdk 8 есть опция, которая может сделать это вызывают эти изменения во время выполнения – the8472

+0

Итак, если оба S1 и S3 имеют один и тот же строковый литерал/константу. В случае 'String S1 = new String (" TestString ");' S1 имеет ссылку, то есть он сохраняет адрес памяти того места, где фактически хранилась константа «TestString», а также S3, потому что (как сказано выше делиться одним и тем же литералом). У меня все еще есть один вопрос, хотя, когда мы сравниваем ссылки S1 и S3, то почему они не равны (они должны иметь одинаковые адреса памяти)? – Navneet

0

если (S1 == S2), мы получаем false.

Это потому, что у вас есть три разные строки, S1, S2 и строковый литерал. S1 и S2 являются копиями объекта String и имеют разные ссылки. Таким образом, ни один из них не является ==.

Мой вопрос: где был строковый литерал «TestString», который был передан в созданном конструкторе?

Он был создан в куче, как и все другие объекты (С Java 6) Он был также добавлен к Струнный стажера() пул так что любой другой строковый литерал, который, как же будет и тот же объект.

Является ли он таким же, как строковый литерал/константа?

Все строковые литералы с одинаковым содержимым будут одним и тем же объектом.

String S3 = "TestString"; это не должно создавать новый строковый литерал

Исправить. Строковый литерал уже создан.

сравнения, если (S1 == S3) должен дать мне истинное

Я понятия не имею, почему. S1 является копией строкового литерала, а не строковым литералом.

но он дает ложные данные.

как и ожидалось.

Так что я не могу понять, где и когда этот строковый литерал передается в создаваемом конструкторе.

Перед Java 7 строковые литералы были созданы, когда класс был загружен, в Java 7+ он создается, когда он впервые используется.

если оба S1 и S3 одни и те же строки буквальным/константа

до Java 6, они разделяют те же основные символ []. Из Java 7 это неверно. Объекты String всегда были и всегда будут разными.

S1 имеет ссылку т.е. он хранит адрес памяти места, где константа «TestString» был на самом деле хранится

S1 является копией, так что хранить ссылку на копию строкового литерала ,

я еще один вопрос, хотя, что, если мы сравним S1 и S3 ссылок мудро, то почему они не равны (они должны быть холдинговыми одними и теми же адреса памяти)

Они имеют разные адреса, поэтому == дает false.

S1 и S2 находятся в стеке, и они содержат значения адресов соответствующих объектов, на которые они ссылаются, из кучи.Таким образом, S1 и S2 будут занимать разные места (адреса).

Первоначально S1 и S2 имеют другое местоположение и указывают на разные местоположения. Однако, когда код запускается в машинный код для фактического запуска, его можно оптимизировать таким образом, чтобы переменные находились в регистре, а не в стеке, и любая переменная, которая не используется, отбрасывается. то есть может быть, что никаких объектов никогда не существует.