char[] value
и int hash
. В поле hash
кэшируется хэш-сумма при первом подсчете для соблюдения контракта метода hashCode.До Java 7 были еще поля
offset
и count
– чтобы переиспользовать без пересоздания массивы из билдеров и других строк. В современной джаве от этого отказались в угоду меньшего потребления памяти.Изначально все строки хранились в кодировке UTF-16, каждый символ занимал по два байта и умещался в
char
. Однако выяснилось, что статистически большинство строк содержит только ASCII-символы, которые вмещаются в один байт и составляют кодировку LATIN-1. То есть старший байт в большинстве char
остается нулевым, и строки наполовину состоят из пустоты. А примерно четверть памяти приложений состоит из одних только строк.В Java 6 была введена экспериментальная фича Compressed Strings – способность строки хранить строки в LATIN-1 в массиве
byte
вместо char
. С этой фичей был ряд проблем, и позднее ее убрали. Снова сжатие строк появилось в Java 9 – теперь оно называется Compact Strings и включено по умолчанию. В классе String появилось поле
coder
, которое переключает кодировки, и статический флаг COMPACT_STRINGS
, выключающий фичу вообще. Тип массива value
окончательно изменился с char[]
на byte[]
.Для полного обзора особенностей класса String стоит посмотреть доклады Алексея Шипилёва (1, 2).