Никакого особого значения. Я просто имел в виду очень важно. То есть java.lang.Stringимеют особое отношение к языку Java.
johnchen902
16
Кто сказал, что строка "класс, как и любой другой"? Это очень особенный класс, в отличие от любого другого. Поскольку ваше предположение неверно, вопрос на самом деле не отвечает.
Эрик Липперт
5
То, что предположение ложно, не означает, что вопрос не несет ответственности. И правильный ответ уже имеет 197 голосов.
Разработчики Java решили сохранить примитивные типы в объектно-ориентированном языке, вместо того чтобы делать все объектами, чтобы повысить производительность языка. Примитивы хранятся в стеке вызовов, которые требуют меньше места для хранения и дешевле манипулировать. С другой стороны, объекты хранятся в куче программы, что требует сложного управления памятью и большего объема памяти.
По соображениям производительности Java String предназначена для того, чтобы находиться между примитивом и классом.
Примечание. Строковые литералы хранятся в общем пуле. Это облегчает совместное использование хранилища для строк с одинаковым содержимым для сохранения хранилища.Stringобъекты, выделенные через новый оператор, хранятся в heap, и для этого же содержимого нет общего хранилища.
Обратите внимание, что «общий пул» обычно является частью кучи.
Йоахим Зауэр
3
@JoachimSauer Да .. с небольшими выгодами :) добавил, что в примечании. Спасибо за запоминание.
Суреш Атта
2
Так что быстрее написать String s1 = "Hello"; чем String s2 = новая строка («Привет») ;?
user2097804
28
Я бы добавил, что в вашем примере s1 == s2 == s3, но s4! = S5
Альфредо Осорио
8
@AndrewJanke в недавней горячей точке jvm (7), пул строк не в perm gen, а в Java 8
perm
50
Java рассматривает String как специальный класс, который можно инициализировать двумя способами
Прямое присвоение литерала
String a ="adsasdf";
В качестве других объектов используется новое ключевое слово
String a =newString("adsasdf");
Вы должны быть особенно внимательны, если хотите сравнить со ==знаком:
String a ="asdf";String b ="asdf";System.out.println(a == b);// TrueSystem.out.println(a.equals(b));// TrueString a =newString("asdf");String b =newString("asdf");System.out.println(a == b);// FalseSystem.out.println(a.equals(b));// True
Это потому, что в первом случае объекты a и b хранятся в вызываемом literal poolобъекте, и они оба ссылаются на один и тот же объект, поэтому они равны в обоих отношениях.
Но во втором случае a и b ссылаются на разные объекты, например, когда мы инициализируем любые другие объекты. поэтому они неравны по сравнению с ==оператором, тогда как они равны по значениям.
Я также не знал, что «нулевой тип» является правильным типом в Java. Это очень полезная информация, вы должны увеличить размер шрифта.
Грижеш Чаухан,
1
@GrijeshChauhan: ну, «нулевой тип» - это просто изящная формулировка, позволяющая nullприсваивать любое значение любой переменной ссылочного типа. Это не интересный тип, в противном случае.
Иоахим Зауэр
15
Это особенность языка Java. Строковые литералы в исходном коде получают специальную обработку.
Спецификация языка здесь просто говорит, что строковый литерал имеет Stringтип
Строки очень часто используются в языке программирования. Поскольку Java является объектно-ориентированным, строка является объектом. Чтобы избежать громоздкой новой строки ("someString"); оператор каждый раз, когда вам нужен строковый объект java позволяет вам просто создать строковый объект, используя строковый литерал.
Но вы должны иметь в виду равенство строк. Вот короткий тест JUnit, чтобы продемонстрировать, что я имею в виду.
@Testpublicvoid stringTest(){// a string literal and a string object created // with the same literal are equal
assertEquals("string",newString("string"));// two string literals are the same string object
assertSame("string","string");// a string literal is not the same object instance // as a string object created with the same string literal
assertFalse("string"==newString("string"));// java's String.intern() method gives you the same// string object reference for all strings that are equal.
assertSame("string",newString("string").intern());}
Если бы вы могли только инициализировать строку с помощью new String(String src), то вы бы даже не смогли дать конструктору строковый литерал. Вам нужно будет инициализировать char [], а затем использовать String(char [] src)конструктор для создания строки, или вам придется читать строку из файла.
AJMansfield
Это не правильно. Строковый литерал - это только последовательность символов в исходном файле, заключенная в двойные кавычки. Java автоматически создает экземпляр строки, используя этот литерал. Поэтому литерал и объект String равны, но они не совпадают. Java также может быть реализован таким образом, что вы должны использовать new String (""); создать экземпляр объекта String, но это только усложнит нашу жизнь. Поэтому, когда вы пишете новую строку («строка»), Java создает объект String для литерала «строка» и передает этот строковый объект создателю новой строки.
Рене Линк
2
Просто чтобы упомянуть. Строковый литерал - это ссылка на экземпляр класса String, который вы можете написать так:
- String - это класс в Java . Вы правы в этом, поэтому мы всегда можем инициализировать с newключевым словом.
- Но когда мы делаем что-то вроде:
String s = "";
Вышеприведенный оператор помечается компилятором как специальный объект String, а затем JVM во время загрузки класса (загрузка выполняется до инициализации), видит это так называемый строковый литерал , который хранится в пуле строкового литерала .
- Таким образом, String может быть создан с использованием new()и с помощью ""метода, но последний предоставляет строковый литерал, который остается в куче, даже если нет ссылки на этот строковый объект, поскольку он имеет ссылку из пула строковых литералов.
Процесс, который вы описываете, - это не то, что на самом деле делает Java: как уже говорили другие, "hello"это строковый литерал, который компилятор помещает в пул констант, см. JLS §3.10.5 и JVMS §5.1 .
siegi
1
Java.lang.Stringэто не просто класс. Это неотъемлемая часть основного языка. У компилятора есть синтаксический сахар для него. Например, ""это как сокращение для new String(""). При написании ""компилятор оптимизирует идентичные строки для одного и того же экземпляра для экономии места."a" + 5 == "a5" ==> true
У компилятора есть синтаксический сахар для многих вещей, включая отсутствие необходимости вставлять / снимать коробку между версиями объекта и их нативными типами, нет родительских средств Object, конструктор по умолчанию, ...
""это не сокращение для new String(""). Если вы используете "", первое, что будет сделано, - это поиск совпадений в пуле строк JVM, и если это так, он вернет эту строку. Используя new String(""), вы всегда будете создавать новую строку, даже если сама строка уже существует в пуле строк (поскольку она не будет храниться в пуле строк).
g00glen00b
Я обновил свой ответ. Используют ли люди это в своих интересах, например, используют строковые константы как эквивалент типа символа Лисп?
" "
это уже строка!java.lang.String
имеют особое отношение к языку Java.Ответы:
Java String является особенной
Например
Примечание. Строковые литералы хранятся в общем пуле. Это облегчает совместное использование хранилища для строк с одинаковым содержимым для сохранения хранилища.
String
объекты, выделенные через новый оператор, хранятся вheap
, и для этого же содержимого нет общего хранилища.источник
Java рассматривает String как специальный класс, который можно инициализировать двумя способами
Прямое присвоение литерала
В качестве других объектов используется новое ключевое слово
Вы должны быть особенно внимательны, если хотите сравнить со
==
знаком:Это потому, что в первом случае объекты a и b хранятся в вызываемом
literal pool
объекте, и они оба ссылаются на один и тот же объект, поэтому они равны в обоих отношениях.Но во втором случае a и b ссылаются на разные объекты, например, когда мы инициализируем любые другие объекты. поэтому они неравны по сравнению с
==
оператором, тогда как они равны по значениям.источник
String получает особую обработку в JLS: это один из двух не примитивных типов, для которых существуют литералы (другой есть
Class
) * .Из JLS :
* ну, есть также «нулевой тип» с его «нулевым литералом»
null
, но большинство людей не считают «нулевой тип» правильным типом.источник
null
присваивать любое значение любой переменной ссылочного типа. Это не интересный тип, в противном случае.Это особенность языка Java. Строковые литералы в исходном коде получают специальную обработку.
Спецификация языка здесь просто говорит, что строковый литерал имеет
String
типисточник
Текст внутри двойных кавычек создает буквальный
String
объект.Код выше создает
String
объект, используя двойные кавычки.источник
Строки очень часто используются в языке программирования. Поскольку Java является объектно-ориентированным, строка является объектом. Чтобы избежать громоздкой новой строки ("someString"); оператор каждый раз, когда вам нужен строковый объект java позволяет вам просто создать строковый объект, используя строковый литерал.
Но вы должны иметь в виду равенство строк. Вот короткий тест JUnit, чтобы продемонстрировать, что я имею в виду.
источник
new String(String src)
, то вы бы даже не смогли дать конструктору строковый литерал. Вам нужно будет инициализироватьchar []
, а затем использоватьString(char [] src)
конструктор для создания строки, или вам придется читать строку из файла.Просто чтобы упомянуть. Строковый литерал - это ссылка на экземпляр класса String, который вы можете написать так:
источник
- String - это класс в Java . Вы правы в этом, поэтому мы всегда можем инициализировать с
new
ключевым словом.- Но когда мы делаем что-то вроде:
String s = "";
Вышеприведенный оператор помечается компилятором как специальный объект String, а затем JVM во время загрузки класса (загрузка выполняется до инициализации), видит это так называемый строковый литерал , который хранится в пуле строкового литерала .
- Таким образом, String может быть создан с использованием
new()
и с помощью""
метода, но последний предоставляет строковый литерал, который остается в куче, даже если нет ссылки на этот строковый объект, поскольку он имеет ссылку из пула строковых литералов.источник
Java делает для нас двухэтапный процесс.
эквивалентно
Как [.NET] [1] получил похожую вещь.
делает
Добавление ссылок: -
источник
"hello"
это строковый литерал, который компилятор помещает в пул констант, см. JLS §3.10.5 и JVMS §5.1 .Java.lang.String
это не просто класс. Это неотъемлемая часть основного языка. У компилятора есть синтаксический сахар для него. Например,""
это как сокращение дляnew String("")
. При написании""
компилятор оптимизирует идентичные строки для одного и того же экземпляра для экономии места."a" + 5 == "a5" ==> true
У компилятора есть синтаксический сахар для многих вещей, включая отсутствие необходимости вставлять / снимать коробку между версиями объекта и их нативными типами, нет родительских средств Object, конструктор по умолчанию, ...
источник
""
это не сокращение дляnew String("")
. Если вы используете""
, первое, что будет сделано, - это поиск совпадений в пуле строк JVM, и если это так, он вернет эту строку. Используяnew String("")
, вы всегда будете создавать новую строку, даже если сама строка уже существует в пуле строк (поскольку она не будет храниться в пуле строк).