String.length: примеры (JAVA)

Работа метода length у строк в Java
Раздел: Строки (String) - базовые операции
String.length: int

Общее описание метода

Метод length() класса java.lang.String возвращает количество char-единиц в строке. Сигнатура метода:

public int length()

Параметры: отсутствуют. Возвращаемое значение: int - ненулевое целое неотрицательное значение, равное числу 16-битных символов (char) в строке. Для пустой строки возвращается 0.

Важно понимать разницу между количеством char-единиц и количеством получаемых визуальных символов (grapheme clusters) или Unicode code points. В Java строки хранятся в UTF-16-представлении: символы из вне BMP (Basic Multilingual Plane), например некоторые эмодзи, кодируются парой суррогатных char-значений и учитываются в length() как 2. Для получения числа Unicode code points используется codePointCount(int beginIndex, int endIndex).

Особенности:

  • Метод принимает ноль аргументов.
  • Возвращает число char-единиц (UTF-16 code units), а не байтов и не обязательно визуальных символов.
  • Вызов на null приводит к NullPointerException.
  • Поведение API не изменялось семантически в последних версиях Java: метод по-прежнему возвращает int и работает за O(1).

Короткие примеры использования

Несколько наглядных примеров кода и их результатов.

Пример 1. Обычная строка

String s = "Hello";
System.out.println(s.length());
5

Пример 2. Пустая строка

String empty = "";
System.out.println(empty.length());
0

Пример 3. Unicode символы из вне BMP (эмодзи)

String emoji = "????"; // U+1F60A
System.out.println(emoji.length());
System.out.println(emoji.codePointCount(0, emoji.length()));
2
1

Пример 4. Вызов на null (ошибка)

String n = null;
// следующая строка приведет к исключению
System.out.println(n.length());
Exception in thread "main" java.lang.NullPointerException
	at ...

Аналоги и близкие методы в Java

Перечисление методов и полей, связанных по смыслу с String.length():

  • CharSequence.length() - интерфейс: если код работает с абстракцией CharSequence, предпочтение в пользу этого метода, так как он универсален для String, StringBuilder, StringBuffer и т.д.
  • StringBuilder.length() и StringBuffer.length() - возвращают количество char-единиц у изменяемых строковых буферов; используются при модификации строки.
  • String.codePointCount(int, int) - возвращает количество Unicode code points на отрезке; применяется, когда важны кодовые точки, а не UTF-16 единицы.
  • String.getBytes(Charset).length - даёт размер в байтах для конкретной кодировки; полезен при работе с сетевым/файловым вводом-выводом.

Когда выбирать:

  • Для простого измерения числа char-единиц подходит length().
  • Для совместимости с разными реализациями символных последовательностей использовать CharSequence.length().
  • Для подсчёта реальных Unicode-символов (code points) использовать codePointCount.
  • Для размера в байтах использовать getBytes(...).length, но учитывать кодировку.

Аналоги в других языках

Краткие заметки о поведении аналогичных функций в популярных языках и примеры.

JavaScript

let s = '????';
console.log(s.length);
2

Как и в Java, .length возвращает число UTF-16 code units. Для числа Unicode code points можно использовать [...s].length или итерацию по строке.

Python (3)

s = '????'
print(len(s))
1

В Python 3 len возвращает число Unicode code points (в современных сборках). Для байтов нужен len(s.encode('utf-8')).

PHP

$s = '????';
echo strlen($s) . PHP_EOL;
echo mb_strlen($s, 'UTF-8') . PHP_EOL;
4
1

strlen возвращает число байтов в строке (в UTF-8 эмодзи 4 байта). Для символов использовать mb_strlen.

C#

string s = "????";
Console.WriteLine(s.Length);
2

Сходно с Java: Length возвращает число char-единиц (UTF-16).

Go

s := "????"
fmt.Println(len(s))
fmt.Println(utf8.RuneCountInString(s))
4
1

В Go len возвращает число байтов. Для числа Unicode-символов использовать utf8.RuneCountInString.

Kotlin

val s = "????"
println(s.length)
2

Kotlin использует UTF-16-представление и поведение length совпадает с Java.

Lua

s = '????'
print(#s)
4

В Lua строки - байтовые последовательности. Для Unicode-символов требуется дополнительная обработка.

SQL (пример MySQL)

SELECT LENGTH('????'), CHAR_LENGTH('????');
4	1

LENGTH возвращает число байтов, CHAR_LENGTH - количество символов (в терминах базы) в данном наборе символов.

Типичные ошибки и их примеры

  • NullPointerException при вызове length() на ссылке null.
  • Путаница между байтами, кодовыми единицами и визуальными символами - ожидание одного результата, а получение другого.
  • Использование length() для подсчёта графем (складывающиеся символы с диакритикой), что даёт неверное число «видимых символов».

Пример 1: NullPointerException

String s = null;
System.out.println(s.length());
Exception in thread "main" java.lang.NullPointerException
	at ...

Пример 2: Неправильное ожидание для эмодзи

String s = "????????"; // флаг, состоит из двух региональных индикаторов
System.out.println(s.length());
System.out.println(s.codePointCount(0, s.length()));
4
2

Ожидание: 1 визуальный символ (флаг). Результат length() = 4, потому что флаг состоит из двух code points, каждый из которых кодируется двумя char.

Пример 3: Ошибка при сравнении с байтовой длиной

String s = "Привет"; // в UTF-8 больше байтов, чем char
System.out.println(s.length());
System.out.println(s.getBytes(StandardCharsets.UTF_8).length);
6
12

Нельзя использовать length() для расчёта места на диске без учёта кодировки.

Изменения в реализации и поведение в новых версиях

API метода length() не претерпевал семантических изменений: он по-прежнему возвращает int и число UTF-16 code units. Существенные изменения внутри платформы:

  • В Java 9 произошли внутренние изменения реализации String (compact strings): переход на хранение в виде byte[] с полем кодера. Это не изменило поведение length(), метод всё так же возвращает количество символных единиц.
  • Появление дополнительных утилит для работы с Unicode (например, методы для работы с code points и методами для обработки пробелов), но length() осталось прежним.

Вывод: коду, использующему length(), изменений не требуется; при необходимости учёта реальных графем или байтов следует применять другие API.

Расширенные и нестандартные примеры использования

1) Подсчёт Unicode code points во всей строке

Пример java
String s = "A????𝄞"; // A, emoji, музыкальная нота (surrogate pair)
int codePoints = s.codePointCount(0, s.length());
System.out.println("length (char units): " + s.length());
System.out.println("code points: " + codePoints);
length (char units): 4
code points: 3

Пояснение: метод length() возвращает количество char-единиц, а codePointCount - количество Unicode code points.

2) Получение подстроки по индексам в терминах code points

Пример java
String s = "A????B";
int startCp = 1; // второй кодовый символ (emoji)
int endCp = 3;   // до конца
int startIndex = s.offsetByCodePoints(0, startCp);
int endIndex = s.offsetByCodePoints(0, endCp);
String sub = s.substring(startIndex, endIndex);
System.out.println(sub);
System.out.println(sub.length());
????B
3

Пояснение: offsetByCodePoints переводит позиции кодовых точек в индексы char, что позволяет корректно извлечь подстроку с учетом суррогатов.

3) Подсчёт визуальных символов (grapheme clusters) с использованием BreakIterator

Пример java
String s = "Z͑́é\uD83D\uDE0A"; // Z + комбинирующие, e + accent, smile
BreakIterator it = BreakIterator.getCharacterInstance(Locale.getDefault());
it.setText(s);
int count = 0;
int start = it.first();
while (start != BreakIterator.DONE) {
    int end = it.next();
    if (end == BreakIterator.DONE) break;
    count++;
}
System.out.println(count);
3

Пояснение: BreakIterator считает графемные кластеры, приближая понятие визуальных символов.

4) Измерение байтового размера в UTF-8 для определения ограничения по трафику

Пример java
String s = "Привет ????";
byte[] utf8 = s.getBytes(StandardCharsets.UTF_8);
System.out.println("chars: " + s.length());
System.out.println("bytes UTF-8: " + utf8.length);
chars: 9
bytes UTF-8: 14

Пояснение: количество char-единиц не равно количеству байтов в UTF-8.

5) Быстродействие: вызов length() за O(1)

Пример java
String s = "a".repeat(10000000);
long t0 = System.nanoTime();
int len = s.length();
long t1 = System.nanoTime();
System.out.println(len);
System.out.println((t1 - t0) + " ns");
10000000
[небольшое число наносекунд, зависит от машины]

Пояснение: length() возвращает заранее известное значение и работает за константное время.

6) Сравнение поведения для разных реализаций CharSequence

Пример java
CharSequence cs1 = "Hello";                // String
CharSequence cs2 = new StringBuilder("Hello");
System.out.println(cs1.length());
System.out.println(cs2.length());
5
5

Пояснение: использование интерфейса CharSequence позволяет писать код, не зависящий от конкретной реализации.

7) Обработка суррогатных пар при обходе строки

Пример java
String s = "\uD83D\uDE00\uD83D\uDE01"; // два emoji
int i = 0;
while (i < s.length()) {
    int cp = s.codePointAt(i);
    System.out.printf("code point: U+%X\n", cp);
    i += Character.charCount(cp);
}
code point: U+1F600
code point: U+1F601

Пояснение: при обходе по char-единицам необходимо использовать методы для работы с кодовыми точками, чтобы не разрезать суррогатные пары.

джава String.length function comments

En
String.length Returns the length of this string