Если String является классом, как и любой другой, как его можно инициализировать с помощью двойных кавычек?
java.lang.String
имеют особое отношение к языку Java.
Если String является классом, как и любой другой, как его можно инициализировать с помощью двойных кавычек?
java.lang.String
имеют особое отношение к языку Java.
Ответы:
Java String является особенной
Разработчики Java решили сохранить примитивные типы в объектно-ориентированном языке, вместо того чтобы делать все объектами, чтобы повысить производительность языка. Примитивы хранятся в стеке вызовов, которые требуют меньше места для хранения и дешевле манипулировать. С другой стороны, объекты хранятся в куче программы, что требует сложного управления памятью и большего объема памяти.
По соображениям производительности Java String предназначена для того, чтобы находиться между примитивом и классом.
Например
String s1 = "Hello"; // String literal
String s2 = "Hello"; // String literal
String s3 = s1; // same reference
String s4 = new String("Hello"); // String object
String s5 = new String("Hello"); // String object
Примечание. Строковые литералы хранятся в общем пуле. Это облегчает совместное использование хранилища для строк с одинаковым содержимым для сохранения хранилища.String
объекты, выделенные через новый оператор, хранятся в heap
, и для этого же содержимого нет общего хранилища.
Java рассматривает String как специальный класс, который можно инициализировать двумя способами
Прямое присвоение литерала
String a = "adsasdf";
В качестве других объектов используется новое ключевое слово
String a = new String("adsasdf");
Вы должны быть особенно внимательны, если хотите сравнить со ==
знаком:
String a = "asdf";
String b = "asdf";
System.out.println(a == b); // True
System.out.println(a.equals(b)); // True
String a = new String("asdf");
String b = new String("asdf");
System.out.println(a == b); // False
System.out.println(a.equals(b)); // True
Это потому, что в первом случае объекты a и b хранятся в вызываемом literal pool
объекте, и они оба ссылаются на один и тот же объект, поэтому они равны в обоих отношениях.
Но во втором случае a и b ссылаются на разные объекты, например, когда мы инициализируем любые другие объекты. поэтому они неравны по сравнению с ==
оператором, тогда как они равны по значениям.
String получает особую обработку в JLS: это один из двух не примитивных типов, для которых существуют литералы (другой есть Class
) * .
Из JLS :
Строковый литерал является ссылкой на экземпляр класса `String [...].
* ну, есть также «нулевой тип» с его «нулевым литералом» null
, но большинство людей не считают «нулевой тип» правильным типом.
null
присваивать любое значение любой переменной ссылочного типа. Это не интересный тип, в противном случае.
Текст внутри двойных кавычек создает буквальный String
объект.
String myString = "Some text";
Код выше создает String
объект, используя двойные кавычки.
Строки очень часто используются в языке программирования. Поскольку Java является объектно-ориентированным, строка является объектом. Чтобы избежать громоздкой новой строки ("someString"); оператор каждый раз, когда вам нужен строковый объект java позволяет вам просто создать строковый объект, используя строковый литерал.
Но вы должны иметь в виду равенство строк. Вот короткий тест JUnit, чтобы продемонстрировать, что я имею в виду.
@Test
public void stringTest() {
// a string literal and a string object created
// with the same literal are equal
assertEquals("string", new String("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" == new String("string"));
// java's String.intern() method gives you the same
// string object reference for all strings that are equal.
assertSame("string", new String("string").intern());
}
new String(String src)
, то вы бы даже не смогли дать конструктору строковый литерал. Вам нужно будет инициализировать char []
, а затем использовать String(char [] src)
конструктор для создания строки, или вам придется читать строку из файла.
- String - это класс в Java . Вы правы в этом, поэтому мы всегда можем инициализировать с new
ключевым словом.
- Но когда мы делаем что-то вроде:
String s = "";
Вышеприведенный оператор помечается компилятором как специальный объект String, а затем JVM во время загрузки класса (загрузка выполняется до инициализации), видит это так называемый строковый литерал , который хранится в пуле строкового литерала .
- Таким образом, String может быть создан с использованием new()
и с помощью ""
метода, но последний предоставляет строковый литерал, который остается в куче, даже если нет ссылки на этот строковый объект, поскольку он имеет ссылку из пула строковых литералов.
Java делает для нас двухэтапный процесс.
String str = "hello";
эквивалентно
char data[] = {'h', 'e', 'l' , 'l', 'o'};
String str = new String(data);
Как [.NET] [1] получил похожую вещь.
String(Char[]) constructor
делает
String(char[] value)
Добавление ссылок: -
"hello"
это строковый литерал, который компилятор помещает в пул констант, см. JLS §3.10.5 и JVMS §5.1 .
Java.lang.String
это не просто класс. Это неотъемлемая часть основного языка. У компилятора есть синтаксический сахар для него. Например, ""
это как сокращение для new String("")
. При написании ""
компилятор оптимизирует идентичные строки для одного и того же экземпляра для экономии места."a" + 5 == "a5" ==> true
У компилятора есть синтаксический сахар для многих вещей, включая отсутствие необходимости вставлять / снимать коробку между версиями объекта и их нативными типами, нет родительских средств Object, конструктор по умолчанию, ...
""
это не сокращение для new String("")
. Если вы используете ""
, первое, что будет сделано, - это поиск совпадений в пуле строк JVM, и если это так, он вернет эту строку. Используя new String("")
, вы всегда будете создавать новую строку, даже если сама строка уже существует в пуле строк (поскольку она не будет храниться в пуле строк).
" "
это уже строка!