
String в Java – это ссылочный тип, предназначенный для работы с последовательностями символов. Объекты этого класса являются неизменяемыми: после создания изменить их содержимое невозможно. Любое преобразование строки фактически создаёт новый объект в памяти.
Строки хранятся в пуле строк (String Pool), что снижает количество дубликатов и экономит память. Например, при создании строки с помощью литерала компилятор сначала проверяет наличие идентичного объекта в пуле и при совпадении возвращает ссылку на него.
Для изменения строк используют классы StringBuilder и StringBuffer, которые работают с изменяемыми последовательностями символов. StringBuilder быстрее и подходит для многократных преобразований внутри одного потока, а StringBuffer синхронизирован и применяется в многопоточной среде.
При выборе метода работы со строками важно учитывать количество операций конкатенации и форматирования. В простых случаях достаточно String, но при интенсивных изменениях лучше сразу использовать StringBuilder.
String в Java: что это и как используется
Класс String в Java представляет неизменяемую последовательность символов. Любая операция, изменяющая строку, создает новый объект, что важно учитывать при работе с памятью и производительностью.
Создание строк может выполняться разными способами:
- Через строковый литерал:
String s = "Привет"; - Через конструктор:
String s = new String("Привет"); - Из массива символов:
String s = new String(new char[]{'J','a','v','a'});
Основные методы класса:
| Метод | Назначение | Пример |
|---|---|---|
length() |
Возвращает количество символов | "Java".length() // 4 |
charAt(int index) |
Получение символа по индексу | "Java".charAt(1) // 'a' |
substring(int begin, int end) |
Извлечение подстроки | "Программирование".substring(0, 6) // "Програ" |
equals(Object obj) |
Сравнение по содержимому | "Java".equals("Java") // true |
compareTo(String str) |
Лексикографическое сравнение | "A".compareTo("B") // -1 |
toLowerCase(), toUpperCase() |
Изменение регистра | "Java".toUpperCase() // "JAVA" |
trim() |
Удаление пробелов по краям | " test ".trim() // "test" |
split(String regex) |
Разделение строки на части | "a,b,c".split(",") // {"a","b","c"} |
Для частых изменений строк рекомендуется использовать StringBuilder или StringBuffer, так как они работают с изменяемыми последовательностями и не создают лишних объектов.
Создание строк с помощью литералов и конструктора

Строковый литерал в Java задаётся в двойных кавычках, например: String s1 = "Привет";. Такие объекты автоматически помещаются в пул строк, что позволяет JVM переиспользовать их при повторном создании идентичных литералов.
При использовании конструктора создаётся новый объект вне пула: String s2 = new String("Привет");. В этом случае формируется отдельный экземпляр, даже если в пуле уже есть строка с тем же содержимым. Это приводит к избыточным затратам памяти.
Для сравнения: s1 == "Привет" вернёт true, так как оба объекта указывают на одну строку из пула. А s2 == "Привет" даст false, поскольку s2 ссылается на новый объект. Для корректной проверки содержимого всегда используйте метод equals().
Рекомендуется применять литералы, если нет особых причин создавать отдельный экземпляр. Конструктор new String() оправдан только при необходимости получить копию, которая не связана с пулом.
Основные методы класса String для работы с текстом

Класс String предоставляет множество методов для анализа и преобразования текста. Ниже приведены наиболее применяемые.
- length() – возвращает количество символов в строке.
- charAt(int index) – возвращает символ по указанному индексу.
- substring(int beginIndex, int endIndex) – извлекает подстроку.
- indexOf(String str) – ищет позицию первого вхождения подстроки.
- lastIndexOf(String str) – ищет позицию последнего вхождения подстроки.
- equals(Object obj) – проверяет полное совпадение строк.
- equalsIgnoreCase(String another) – сравнивает строки без учета регистра.
- startsWith(String prefix) и endsWith(String suffix) – проверяют начало и конец строки.
- toLowerCase() и toUpperCase() – меняют регистр символов.
- trim() – удаляет пробелы в начале и в конце.
- replace(char oldChar, char newChar) и replace(CharSequence target, CharSequence replacement) – заменяют символы или подстроки.
- split(String regex) – разбивает строку по заданному разделителю.
- join(CharSequence delimiter, CharSequence… elements) – объединяет элементы через указанный разделитель.
Рекомендуется использовать методы equals() и equalsIgnoreCase() вместо оператора == для корректного сравнения строк. Для работы с большими текстовыми изменениями предпочтительнее применять StringBuilder или StringBuffer, так как String является неизменяемым.
Сравнение строк: equals, compareTo и оператор ==
Метод equals() проверяет равенство содержимого объектов String. Если две строки имеют одинаковую последовательность символов, результат будет true. Например: "test".equals("test") вернёт true.
Метод compareTo() используется для лексикографического сравнения. Он возвращает число: 0, если строки идентичны; отрицательное значение, если текущая строка меньше по порядку; положительное – если больше. Пример: "abc".compareTo("abd") даст -1.
Оператор == сравнивает ссылки на объекты, а не содержимое. Две переменные будут равны только в случае, если они указывают на один и тот же объект в памяти. Например, String a = "java"; String b = "java"; – результат a == b будет true из-за интернирования строк, но new String("java") == new String("java") вернёт false.
Рекомендация: использовать equals() для проверки содержимого, compareTo() – для сортировки и упорядочивания, а оператор == – только для проверки ссылочной идентичности.
Неизменяемость строк и её последствия для кода
Класс String в Java объявлен как final, а внутреннее значение хранится в массиве char[], доступ к которому осуществляется только для чтения. После создания объекта его содержимое изменить невозможно: любая операция, например concat(), substring(), replace(), формирует новый объект.
Последствия неизменяемости:
- Безопасность: строки можно передавать в разные части программы без риска изменения оригинала.
- Хэширование: значение hashCode() стабильно, поэтому строки эффективно используются в HashMap, HashSet и других коллекциях.
- Память: одинаковые строковые литералы хранятся в пуле строк (String Pool), что сокращает дублирование.
- Производительность: частые конкатенации через оператор
+или метод concat() создают множество временных объектов, что увеличивает нагрузку на сборщик мусора.
Рекомендации при работе со строками:
- Для многократных изменений использовать StringBuilder или StringBuffer.
- При сравнении всегда применять equals(), а не оператор ==.
- Избегать конкатенации в циклах, заменяя её на StringBuilder.
- Для интернирования использовать метод intern(), если важно хранение в пуле.
Использование StringBuilder и StringBuffer для изменения строк
В Java строки, представленные объектами класса String, неизменяемы. Любое изменение строки создает новый объект в памяти, что снижает производительность при множественных операциях с текстом. Для изменения строк без создания новых объектов применяют StringBuilder и StringBuffer.
StringBuilder подходит для однопоточных приложений. Его методы append(), insert(), delete(), replace() и reverse() позволяют эффективно добавлять, удалять, заменять или переворачивать содержимое строки. Например, append() соединяет строки без создания дополнительных объектов, а insert() вставляет текст в произвольную позицию.
StringBuffer аналогичен StringBuilder, но безопасен для многопоточной среды. Все его методы синхронизированы, что предотвращает одновременное изменение строки несколькими потоками. Однако эта синхронизация делает StringBuffer медленнее, чем StringBuilder в однопоточных сценариях.
При выборе между ними учитывают контекст: для большинства задач без многопоточности рекомендуется StringBuilder, если потокобезопасность требуется – StringBuffer. Для операций, включающих многократное изменение строки, использование этих классов значительно уменьшает расход памяти и повышает скорость работы программы по сравнению с обычными строками String.
Пример использования StringBuilder:
StringBuilder sb = new StringBuilder("Пример");
sb.append(" текста");
sb.replace(0, 7, "Тест");
System.out.println(sb); // Выведет "Тест текста"
StringBuffer используется аналогично, меняется только синтаксис и потоко-безопасность:
StringBuffer sbf = new StringBuffer("Данные");
sbf.append(" обновлены");
sbf.delete(0, 6);
System.out.println(sbf); // Выведет " обновлены"
Работа со строками в массивах и коллекциях
Многомерные массивы позволяют работать с таблицами строк: String[][] table = {{"A1","A2"},{"B1","B2"}};. Доступ к элементу осуществляется через два индекса: table[1][0] вернёт "B1".
Коллекции, например ArrayList<String>, обеспечивают динамическое изменение размера. Создание коллекции: List<String> list = new ArrayList<>();. Добавление строки выполняется методом add: list.add("новая строка");, удаление – методом remove: list.remove(0);. Доступ к элементу осуществляется через get: list.get(2).
Для перебора элементов массивов и коллекций используется цикл for или for-each. Пример для массива: for(String s : array){ System.out.println(s); }. Для коллекции: for(String s : list){ System.out.println(s); }.
Методы contains, indexOf и size помогают проверять наличие строки, получать индекс и размер коллекции: list.contains("тест") возвращает true, если строка присутствует.
При работе с массивами и коллекциями рекомендуется использовать неизменяемые строки и избегать частого создания новых объектов внутри циклов, чтобы снизить нагрузку на сборщик мусора.
Вопрос-ответ:
Что такое String в Java и чем он отличается от других типов данных?
String в Java — это объект, который хранит последовательность символов. В отличие от примитивных типов, таких как int или boolean, String является ссылочным типом. Это означает, что переменная типа String хранит ссылку на объект в памяти, а не сам набор символов. Кроме того, строки в Java неизменяемы: любые изменения создают новый объект, а исходный остаётся без изменений.
Как создать строку в Java и какие способы существуют?
Строку можно создать несколькими способами. Самый распространённый — присвоить литерал строковой переменной, например, String s = «Привет»;. Также можно использовать конструктор класса String: String s = new String(«Привет»);. Кроме того, строки можно строить динамически с помощью методов класса StringBuilder или StringBuffer, особенно если нужно часто изменять содержимое.
Какие методы String чаще всего используются для работы со строками?
У класса String есть множество методов. Например, length() возвращает количество символов, charAt(int index) позволяет получить символ по позиции, substring(int start, int end) извлекает часть строки. Для сравнения строк применяются equals() и equalsIgnoreCase(). Для поиска подстроки есть indexOf(), а replace() и replaceAll() позволяют менять символы или последовательности символов. Также полезны toUpperCase() и toLowerCase() для изменения регистра.
Почему строки в Java называются неизменяемыми и какие последствия это имеет?
Неизменяемость означает, что после создания объекта String его содержимое нельзя изменить. Любое изменение создаёт новый объект. Это снижает риск ошибок при совместной работе с одними и теми же строками в разных частях программы. Кроме того, неизменяемые строки безопасны для использования в коллекциях и в многопоточном коде. Недостатком является то, что частые изменения строк могут приводить к созданию большого количества объектов, поэтому для таких случаев лучше использовать StringBuilder.
Как сравнивать строки в Java и почему нельзя использовать оператор ==?
Оператор == сравнивает ссылки на объекты, а не их содержимое. Поэтому строки с одинаковыми символами, но разными объектами, при сравнении через == будут считаться разными. Для сравнения содержимого используют метод equals(), а для игнорирования регистра — equalsIgnoreCase(). Также существует метод compareTo(), который возвращает число, показывающее лексикографическое отношение строк, что удобно для сортировки.
