1. Введение
Java String
— один из самых важных классов, и мы уже рассмотрели многие его аспекты в нашей серии руководств, связанных со строками
.
В этом руководстве мы сосредоточимся на инициализации строк в Java.
2. Создание
Прежде всего, мы должны помнить, как создаются String в Java.
Мы можем использовать новое
ключевое слово или литеральный синтаксис:
String usingNew = new String("foreach");
String usingLiteral = "foreach";
И также важно, чтобы мы понимали, как String
управляются в специализированном пуле .
3. Только объявление строки
Во-первых, давайте просто объявим String
без явного присвоения значения.
Мы можем сделать это локально или в качестве переменной-члена:
public class StringInitialization {
String fieldString;
void printDeclaredOnlyString() {
String localVarString;
// System.out.println(localVarString); -> compilation error
System.out.println(fieldString);
}
}
Как мы видим, если мы попытаемся использовать localVarString
до присвоения ему значения, мы получим ошибку компиляции. С другой стороны, консоль покажет « null»
для значения fieldString
.
Видите ли, переменные-члены инициализируются значением по умолчанию при создании класса, нулевым
в случае String
. Но мы должны сами инициализировать локальные переменные.
Если мы присвоим localVarString
значение null
, мы увидим, что они действительно теперь равны:
String localVarString = null;
assertEquals(fieldString, localVarString);
4. Инициализация строки с помощью литералов
Давайте теперь создадим два String
, используя один и тот же литерал:
String literalOne = "ForEach";
String literalTwo = "ForEach";
Мы подтвердим, что создан только один объект, сравнив ссылки:
assertTrue(literalOne == literalTwo);
Причина этого восходит к тому факту, что String
хранятся в пуле . literalOne
добавляет строку
«foreach» в пул, а literalTwo
повторно использует ее.
5. Инициализация строки с помощью
new
Однако мы увидим другое поведение, если будем использовать новое
ключевое слово.
String newStringOne = new String("ForEach");
String newStringTwo = new String("ForEach");
Хотя значение обоих String
будет таким же, как и раньше, на этот раз нам понадобятся разные объекты:
assertFalse(newStringOne == newStringTwo);
6. Пустая строка
Давайте теперь создадим три пустых String
s:
String emptyLiteral = "";
String emptyNewString = new String("");
String emptyNewStringTwo = new String();
Как мы уже знаем, emptyLiteral будет
добавлен в пул строк
, а два других — непосредственно в кучу.
Хотя это не будут одни и те же объекты, все они будут иметь одинаковое значение :
assertFalse(emptyLiteral == emptyNewString)
assertFalse(emptyLiteral == emptyNewStringTwo)
assertFalse(emptyNewString == emptyNewStringTwo)
assertEquals(emptyLiteral, emptyNewString);
assertEquals(emptyNewString, emptyNewStringTwo);
7. нулевые
значения
Наконец, давайте посмотрим, как ведут себя null String
s.
Давайте объявим и инициализируем нулевую строку
:
String nullValue = null;
Если бы мы напечатали nullValue
, то увидели бы слово «null», как видели ранее. И если бы мы попытались вызвать какие-либо методы для nullValue,
то получили бы исключение NullPointerException,
как и ожидалось.
Но почему печатается «null»? Что такое ноль
на самом деле?
Что ж, спецификация JVM говорит, что null
является значением по умолчанию для всех ссылок, поэтому оно не привязано конкретно к String
. И на самом деле спецификация не требует какой-либо конкретной кодировки значения для null
.
Итак, откуда тогда берется «null» для печати строки
?
Если мы посмотрим на реализацию PrintStream#
println
, то увидим, что она вызывает String#valueOf
:
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
И если мы посмотрим на String#valueOf,
то получим наш ответ:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
И, очевидно, в этом причина «нуля».
8. Заключение
В этой статье мы рассмотрели инициализацию строк .
Мы объяснили разницу между объявлением и инициализацией. Мы также коснулись использования нового
и литерального синтаксиса.
Наконец, мы рассмотрели, что значит присвоить String
нулевое
значение , как нулевое
значение представляется в памяти и как оно выглядит при печати.
Все примеры кода, использованные в статье, доступны на Github .