На практическом уровне основное различие между String
и char[]
состоит в том, что экземпляры первого являются неизменяемыми, а экземпляры последнего являются изменяемыми. И, конечно же, API-интерфейс String предлагает широкий спектр полезных методов для работы со строками.
Итак, давайте поговорим о лингвистических сходствах и различиях.
Во-первых, (несмотря на то, что вы, возможно, слышали) строки и экземпляры массивов в Java оба являются объектами . Согласно спецификации языка Java:
4.3.1 Объекты Объект - это экземпляр класса или массив.
Контрольные значения (часто просто
ссылки) являются указателями на эти
объекты и специальная нулевая ссылка,
который ссылается на отсутствие объекта.
... где класс строки равен java.lang.String
.
Лингвистическое различие между массивами и другими типами объектов заключается в том, что тип массива не является обычным классом Java. Например:
- Типы массивов объявляются с синтаксисом, отличным от обычных классов.
- Экземпляры массива создаются с синтаксисом, отличным от обычных экземпляров класса.
- Типы массивов не могут быть названы на уровне исходного кода Java.
- Вы не можете объявить подтип / подкласс типа массива.
Но все типы массивов являются (прямыми) подтипами java.lang.Object
, что означает, что вы можете (например) присвоить массив переменной типа Object
и вызывать методы в Object API. (И есть некоторые интересные вещи, которые вы можете сделать с помощью этих методов, чтобы продемонстрировать «объектность» массива ... но я отвлекся)
Так что насчет строк? Как упоминалось выше, «строка» - это обычный объект, который является экземпляром класса java.lang.String
. В этом классе нет ничего необычного с лингвистической точки зрения. Он объявляется как «окончательный», поэтому вы не можете объявлять подтипы, но это не является необычным.
Что делает String
немного особенным по сравнению с другими классами, так это то, что язык Java предоставляет некоторые лингвистические конструкции для поддержки строк:
- Существует специальный буквенный синтаксис
String
для получения строк, содержимое которых можно определить во время компиляции.
- Оператор '+' перегружен для поддержки
String
конкатенации.
- Начиная с Java 7, оператор
switch
поддерживает включение значений String
.
- Спецификация языка Java определяет / предполагает, что класс java.lang.String имеет определенные свойства и методы; например что строки являются изменяемыми, что существует метод
concat
, что строковые литералы "интернированы".
Кстати, ответ о том, что все экземпляры строк содержатся в пуле строк, неверен. Строки помещаются в пул только тогда, когда они интернированы, и это происходит автоматически только для строковых литералов и для строк, значения которых можно вычислить во время компиляции. (Вы можете принудительно интернировать экземпляр строки, вызвав метод String.intern()
, но это немного дорого и, как правило, не очень хорошая идея.)