Типы данных Java: строка и массив - PullRequest
4 голосов
/ 07 августа 2009

Я изучал Java-учебник Sun Microsystem и получил несколько вопросов, читая следующее:

Ввод / вывод из командной строки: Консольный объект

"Second, readPassword returns a character array, not a String, so the password can be
 overwritten, removing it from memory as soon as it is no longer needed."

Мои вопросы:

1) Чем отличаются массивы и строки в Java от других типов данных, таких как типы данных-значения (int, float, boolean и т. Д.) И ссылочных типов (определяемые пользователем объекты и т. Д.)?

2) Можете ли вы уточнить приведенное выше утверждение о массиве символов и строке?

P.S:

Разъяснение к Q1: я хотел спросить в Q1 больше о том, что такое массивы и строки как типы данных в Java ... С их объектно-подобными атрибутами я легко запутываюсь, когда кто-то утверждает, что строки и массивы не объекты в строгом смысле ...

Ответы [ 3 ]

4 голосов
/ 07 августа 2009

На практическом уровне основное различие между 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(), но это немного дорого и, как правило, не очень хорошая идея.)

4 голосов
/ 07 августа 2009

A String хранит свое содержимое внутри как массив chars.Вы не можете манипулировать этим массивом напрямую (без отражения), поскольку Strings являются неизменяемыми.

Причина, по которой пароль будет в char[], заключается в том, что вы можете немедленно перезаписать его в памяти.Если бы это было в String, вам пришлось бы ждать следующей сборки мусора, и вы никогда не знаете, как долго это будет;злоумышленник потенциально может прочитать его из памяти раньше.

1 голос
/ 07 августа 2009

Как говорили другие, String не изменчив, поэтому вы не можете уничтожить его самостоятельно. Даже после сборки мусора память может оставаться нетронутой. Таким образом, все протоколы безопасности определяют конфиденциальные данные как массив байтов, так что вы можете сделать это,

  char[] password = "secret";

  // After using it
  for (int i; i < password.length; i++) 
     password[i] = 0;
  password = null;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...