Класс String в Java предназначен для работы со строками в Java. Все строковые литералы, определенные в Java программе (например, "abc") — это экземпляры класса String. Давай посмотрим на его ключевые характеристики:
![Класс String в Java - 1]()
- Класс реализует интерфейсы
SerializableиCharSequence. Поскольку он входит в пакетjava.lang, его не нужно импортировать. - Класс String в Java — это final класс, который не может иметь потомков.
- Класс String — immutable класс, то есть его объекты не могут быть изменены после создания. Любые операции над объектом String, результатом которых должен быть объект класса String, приведут к созданию нового объекта.
- Благодаря своей неизменности, объекты класса String являются потокобезопасными и могут быть использованы в многопоточной среде.
- Каждый объект в Java может быть преобразован в строку через метод
toString, унаследованный всеми Java-классами от классаObject.

Работа с Java String
Это один из самых часто используемых классов в Java. В нем есть методы для анализа определенных символов строки, для сравнения и поиска строк, извлечения подстрок, создания копии строки с переводом всех символов в нижний и верхний регистр и прочие. Список всех методов класса String можно изучить в официальной документации. Также в Java реализован несложный механизм конкатенации (соединения строк), преобразования примитивов в строку и наоборот. Давай рассмотрим некоторые примеры работы с классом String в Java.Создание строк
Проще всего создать экземпляр класса String, присвоив ему значение строкового литерала:
String s = "I love movies";
Однако у класса String есть много конструкторов, которые позволяют:
- создать объект, содержащий пустую строку
- создать копию строковой переменной
- создать строку на основе массива символов
- создать строку на основе массива байтов (с учетом кодировок)
- и т.д.
String Pool и интернирование строк
Теперь давай разберемся, что происходит в памяти, когда мы создаем строки разными способами. Это поможет тебе понимать, как Java оптимизирует работу со строками и почему иногда важен способ их создания. Что такое String Pool? String Pool (пул строк) — это специальная область памяти в Java, где хранятся строковые литералы. Когда ты создаешь строку с помощью литерала, Java сначала проверяет: есть ли уже такая строка в пуле? Если да — просто возвращает ссылку на существующий объект. Если нет — создает новый и помещает его в пул. Это экономит память, ведь одинаковые строки не дублируются! Практический пример:public static void main(String[] args) {
String a = "JavaRush";
String b = "JavaRush";
System.out.println(a == b); // true
System.out.println(a.equals(b)); // true
}
Почему a == b возвращает true?
Потому что обе переменные ссылаются на один и тот же объект в String Pool. Java увидела, что строка "JavaRush" уже существует в пуле, и просто вернула ссылку на неё.
А что с конструктором?
Когда ты создаешь строку через конструктор new String(), Java всегда создает новый объект в памяти (в heap), даже если такая строка уже есть в пуле:public static void main(String[] args) {
String c = new String("JavaRush");
String d = new String("JavaRush");
System.out.println(c == d); // false
System.out.println(c.equals(d)); // true
}
Почему c == d возвращает false?
Потому что c и d ссылаются на два разных объекта в памяти, хотя содержат одинаковый текст. Оператор == сравнивает ссылки (адреса в памяти), а метод equals() — содержимое строк.
Метод intern() — принудительное интернирование
Если ты создал строку через конструктор, но хочешь поместить её в String Pool, используй метод intern():
public static void main(String[] args) {
String e = new String("JavaRush").intern();
String f = new String("JavaRush").intern();
System.out.println(e == f); // true
System.out.println(e.equals(f)); // true
}Метод intern() проверяет: есть ли такая строка в пуле? Если да — возвращает ссылку на неё. Если нет — добавляет в пул и возвращает ссылку.Литералы vs конструктор: что выбрать?
Когда использовать литералы? В 99% случаев используй литералы (двойные кавычки):String name = "Alex"; // ✅ Правильно
Почему?
- Экономит память (благодаря String Pool)
- Быстрее работает
- Проще и понятнее код
- Это стандартная практика в Java
Когда использовать конструктор?
Конструктор new String() нужен очень редко, только если тебе действительно нужен новый объект в памяти. Например:
// Редкий случай: нужна копия строки из ненадежного источника
String userInput = getUserInput(); // может содержать огромную строку
String safeString = new String(userInput.substring(0, 10));
// Теперь safeString — отдельный объект, и огромная userInput может быть удалена сборщиком мусора
Но даже такие случаи встречаются крайне редко. Запомни правило: всегда используй литералы, если нет веской причины делать иначе.
❌ Типичная ошибка новичков:
String s = new String("Hello"); // ❌ Плохо! Создается два объекта
В этом коде создается два объекта:
1. Литерал "Hello" в String Pool
2. Новый объект в heap через конструктор
Правильно:
String s = "Hello"; // ✅ Хорошо! Один объект в String Pool
Сложение строк
Сложить две строки в Java довольно просто, воспользовавшись оператором+. Java позволяет складывать друг с другом и переменные, и строковые литералы:
public static void main(String[] args) {
String day = "День";
String and = "и";
String night = "Ночь";
String dayAndNight = day + " " + and + " " + night;
}
Складывая объекты класса String с объектами других классов, мы приводим последние к строковому виду. Преобразование объектов других классов к строковому представлению выполняется через неявный вызов метода toString у объекта. Продемонстрируем это на следующем примере:
public class StringExamples {
public static void main(String[] args) {
Human max = new Human("Макс");
String out = "Java объект: " + max;
System.out.println(out);
// Вывод: Java объект: Человек с именем Макс
}
static class Human {
private String name;
public Human(String name) {
this.name = name;
}
@Override
public String toString() {
return "Человек с именем " + name;
}
}
}
Сравнение строк
Для сравнения строк можно воспользоваться методомequals():
public static void main(String[] args) {
String x = "Test String";
System.out.println("Test String".equals(x)); // true
}
Когда при сравнении строк нам не важен регистр, нужно использовать метод equalsIgnoreCase():
public static void main(String[] args) {
String x = "Test String";
System.out.println("test string".equalsIgnoreCase(x)); // true
}
Перевод объекта/примитива в строку
Для перевода экземпляра любого Java-класса или любого примитивного типа данных к строковому представлению, можно использовать методString.valueOf():
public class StringExamples {
public static void main(String[] args) {
String a = String.valueOf(1);
String b = String.valueOf(12.0D);
String c = String.valueOf(123.4F);
String d = String.valueOf(123456L);
String s = String.valueOf(true);
String human = String.valueOf(new Human("Alex"));
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
System.out.println(s);
System.out.println(human);
/*
Вывод:
1
12.0
123.4
123456
true
Человек с именем Alex
*/
}
static class Human {
private String name;
public Human(String name) {
this.name = name;
}
@Override
public String toString() {
return "Человек с именем " + name;
}
}
}
Перевод строки в число
Часто бывает нужно перевести строку в число. У классов оберток примитивных типов есть методы, которые служат как раз для этой цели. Все эти методы начинаются со слова parse. Рассмотрим ниже перевод строки в целочисленное (Integer) и дробное (Double) числа:
public static void main(String[] args) {
Integer i = Integer.parseInt("12");
Double d = Double.parseDouble("12.65D");
System.out.println(i); // 12
System.out.println(d); // 12.65
}
Перевод коллекции строк к строковому представлению
Если нужно преобразовать все элементы некоторой коллекции строк к строковому представлению через произвольный разделитель, можно использовать такие методы класса String Java:join(CharSequence delimiter, CharSequence... elements)join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
delimiter — разделитель элементов, а elements — массив строк / экземпляр коллекции строк.
Рассмотрим пример, в котором мы преобразуем список строк в строку, разделяя каждую точкой с запятой:
public static void main(String[] args) {
List<String> people = Arrays.asList(
"Philip J. Fry",
"Turanga Leela",
"Bender Bending Rodriguez",
"Hubert Farnsworth",
"Hermes Conrad",
"John D. Zoidberg",
"Amy Wong"
);
String peopleString = String.join("; ", people);
System.out.println(peopleString);
/*
Вывод:
Philip J. Fry; Turanga Leela; Bender Bending Rodriguez; Hubert Farnsworth; Hermes Conrad; John D. Zoidberg; Amy Wong
*/
}
Разбиение строки на массив строк
Эту операцию выполняет методsplit(String regex)
В качестве разделителя выступает строковое регулярное выражение regex.
В примере ниже произведем операцию, обратную той, что мы выполняли в предыдущем примере:
public static void main(String[] args) {
String people = "Philip J. Fry; Turanga Leela; Bender Bending Rodriguez; Hubert Farnsworth; Hermes Conrad; John D. Zoidberg; Amy Wong";
String[] peopleArray = people.split("; ");
for (String human : peopleArray) {
System.out.println(human);
}
/*
Вывод:
Philip J. Fry
Turanga Leela
Bender Bending Rodriguez
Hubert Farnsworth
Hermes Conrad
John D. Zoidberg
Amy Wong
*/
}
Определение позиции элемента в строке
В языке Java String предоставляет набор методов для определения позиции символа/подстроки в строке:indexOf(int ch)indexOf(int ch, int fromIndex)indexOf(String str)indexOf(String str, int fromIndex)lastIndexOf(int ch)lastIndexOf(int ch, int fromIndex)lastIndexOf(String str)lastIndexOf(String str, int fromIndex)
ch— искомый символ (char)str— искомая строкаfromIndex— позиция с которой нужно искать элемент- методы
indexOf— возвращают позицию первого найденного элемента - методы
lastIndexOf— возвращают позицию последнего найденного элемента
A, K, Z, Я в английском алфавите, но будем иметь ввиду, что индексация символов в строке в Java начинается с нуля:
public static void main(String[] args) {
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
System.out.println(alphabet.indexOf('A')); // 0
System.out.println(alphabet.indexOf('K')); // 10
System.out.println(alphabet.indexOf('Z')); // 25
System.out.println(alphabet.indexOf('Я')); // -1
}
Извлечение подстроки из строки
Для извлечения подстроки из строки класс String в Java предоставляет методы:substring(int beginIndex)substring(int beginIndex, int endIndex)
public static void main(String[] args) {
String filePath = "D:\\Movies\\Futurama.mp4";
int lastFileSeparatorIndex = filePath.lastIndexOf('\\');
String fileName = filePath.substring(lastFileSeparatorIndex + 1);
System.out.println(fileName); //9
}
Перевод строки в верхний/нижний регистр:
Класс String предоставляет методы для перевода строки в верхний и нижний регистры:toLowerCase()toUpperCase()
public static void main(String[] args) {
String fry = "Philip J. Fry";
String lowerCaseFry = fry.toLowerCase();
String upperCaseFry = fry.toUpperCase();
System.out.println(lowerCaseFry); // philip j. fry
System.out.println(upperCaseFry); // PHILIP J. FRY
}
Новые возможности Java String
Java продолжает развиваться, и класс String получил несколько полезных дополнений в последних версиях. Давай посмотрим на самые важные из них. Text Blocks (Java 15+) Если тебе нужно работать с многострочным текстом, text blocks значительно упростят жизнь:public static void main(String[] args) {
// Старый способ - неудобно и нечитаемо
String json = "{\n" +
" \"name\": \"Philip J. Fry\",\n" +
" \"job\": \"Delivery Boy\"\n" +
"}";
// Новый способ с text blocks - красиво и понятно!
String jsonNew = """
{
"name": "Philip J. Fry",
"job": "Delivery Boy"
}
""";
System.out.println(jsonNew);
}
Text blocks начинаются и заканчиваются тремя двойными кавычками """. Все переносы строк и отступы сохраняются автоматически!
Методы formatted() и format() (Java 15+)
Вместо сложной конкатенации теперь можно использовать удобное форматирование:
public static void main(String[] args) {
String name = "Bender";
int age = 4;
// Старый способ
String message1 = "Привет, я " + name + " и мне " + age + " года";
// Новый способ
String message2 = "Привет, я %s и мне %d года".formatted(name, age);
// Альтернатива
String message3 = String.format("Привет, я %s и мне %d года", name, age);
System.out.println(message2);
}
Полезные методы для проверки строк
В современной Java появились удобные методы для частых операций:
public static void main(String[] args) {
String empty = "";
String spaces = " ";
String text = "JavaRush";
// Проверка на пустоту (Java 11+)
System.out.println(empty.isBlank()); // true
System.out.println(spaces.isBlank()); // true (игнорирует пробелы)
System.out.println(text.isBlank()); // false
// Удаление пробелов с обеих сторон (Java 11+)
String withSpaces = " JavaRush ";
System.out.println(withSpaces.strip()); // "JavaRush"
System.out.println(withSpaces.stripLeading()); // "JavaRush "
System.out.println(withSpaces.stripTrailing()); // " JavaRush"
// Повторение строки (Java 11+)
System.out.println("Ha".repeat(3)); // "HaHaHa"
// Работа со строками как с потоками (Java 11+)
"Line1\nLine2\nLine3".lines()
.forEach(System.out::println);
}
Compact Strings - автоматическая оптимизация (Java 9+)
Начиная с Java 9, класс String стал автоматически оптимизировать память. Если строка содержит только латинские символы (Latin-1), она занимает в два раза меньше памяти!
// Эта строка займет меньше памяти (Latin-1)
String latin = "Hello World"; // 1 байт на символ
// Эта строка займет больше (UTF-16)
String cyrillic = "Привет Мир"; // 2 байта на символ
Это происходит автоматически, тебе ничего делать не нужно. Просто знай, что Java следит за эффективностью использования памяти сама!
Работа с данным классом Java изучается на начальных уровнях онлайн-курса JavaRush:
- Знакомство со String приводится на 1-ом уровне, 4-ой лекции квеста Java Syntax
- Внутреннее устройство String, метод substring изучаются на 2-ом уровне, 3-ей лекции квеста Java Multithreading
- Поиск, получение, удаление подстроки в String изучаются на 2-ом уровне, 4-ой лекции квеста Java Multithreading
- Метод String.format рассматривается на 2-ом уровне, 6-ой лекции квеста Java Multithreading
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ