Разница инициализации строки - PullRequest
5 голосов
/ 04 марта 2012

Во-первых, извинения, если это очень простой вопрос, мне просто интересно узнать разницу между следующими определениями строк

String x= "hello";
String y = new String("hello");

Я знал, что в Java String это класс, он не является ни примитивом, ни оболочкой (поправьте меня, если это заблуждение). Рассмотрим класс A, до сих пор я видел следующие объявления для любого класса. Я думаю, A c; является действительным и A a = new A(); также является действительным. Я запутался с A a ="xyz";, так мы объявили String, как в приведенном выше определении первого типа. Я уверен, что два приведенных выше определения абсолютно разные, например, если я скажу x==y, он вернет false. Я понимаю, что у является ссылкой на объект String. Что такое x там, как оно хранится в памяти, интересно, что я обнаружил, что и x, и y могут получить доступ ко всем методам класса String.

Тогда в чем же преимущество одного над другим? Могу ли я знать применимость каждого из них.

Ответы [ 6 ]

8 голосов
/ 04 марта 2012

Из 2-го издания «Эффективной Явы» Джошуа Блоха:

String s = new String("stringette");// DON'T DO THIS!

Оператор создает новый экземпляр String при каждом его выполнении, и ни одно из этих созданий объекта не является необходимым. Аргумент к String constructor ("stringette") сам по себе является экземпляром String, функционально идентичен всем объектам, созданным конструктор. Если это использование происходит в цикле или в часто вызываемом Метод, миллионы экземпляров String могут быть созданы без необходимости. улучшенная версия просто следующая:

String s = "stringette";
5 голосов
/ 04 марта 2012

Первые пару полученных вами ответов неверны. Там есть разница между двумя утверждениями. Но сначала, версия TL;DR: используйте String x = "hello"; в 99,99999% случаев.

Полный ответ:

Главное различие между этими двумя заключается в том, что в первом случае строка неявно intern ed ; во втором случае это не так. Это очень реальная разница, хотя она вступает в силу только в некоторых ситуациях. Таким образом, в первом случае, если у вас есть какие-либо другие строки с такой же последовательностью символов ("hello"), ваш x будет ссылаться на один общий объект , который используется во всех этих местах ( это полезно, поскольку String экземпляры являются неизменяемыми). Во втором случае вы явно говорите, что вам нужно (по любой причине) иметь экземпляр String с той последовательностью символов, которая отделена от любых других. Для этого есть очень и очень мало причин.

Что касается x==y, в Java вы сравниваете строки на равенство, используя equals, а не ==. Оператор == при использовании со ссылками на объекты сравнивает ссылки (например, указывают ли обе переменные на один и тот же объект), а не содержимое объекта.

Итак: предпочитайте первую форму второй, если у вас нет веских причин для второй.

1 голос
/ 04 марта 2012
String a = "hello"; //this kind of declaration always return "singlton" instance.
String b = "hello";
String c = new String("hello"); //This kind of declaration always return a new instance.

SO a ==b; но a !=c

0 голосов
/ 07 марта 2014

Еще один способ инициализации строки -

String str =("abc");

Сначала кажется, что это приведет к ошибке (из-за скобок), но это не так.Удивительно.

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

Я понимаю, что y является ссылкой на объект String.Что такое х там [...]?

И x, и y являются ссылками на String объекты.x - это ссылка на строку intern ed (как уже писал в своем ответе TJ Crowder), y - это ссылка на второй объект String с таким же содержимым.Это означает:

x == y       --> false
x.equals(y)  --> true
y.equals(x)  --> true

Тогда в чем же преимущество одного над другим. Могу ли я знать применимость каждого из них.

Всегда Использованиепервая, прямая версия.Допустимое исключение only , с которым я когда-либо сталкивался и которое было признано допустимым, является тестовым кодом, который явно хочет убедиться, что тестируемый код не использует == для сравнения строк, но использует надлежащие x.equals(y) метод.

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

Очень просто, значение x является строкой.Обычный java.lang.String.

Вы привыкли к мысли, что существуют литералы для примитивных типов (например, 7, или 3.14159, или true, или 'q'), нокажется, что вы, возможно, не поняли, что есть буквальные формы для некоторых типов объектов.Единственные, о которых я могу думать, это java.lang.String, где вы можете написать "hello", и java.lang.Class, где вы можете написать SomeClass.class.

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