Программирование на Java

       

String


Этот класс используется в Java для представления строк. Он обладает свойством неизменяемости. После того как создан экземпляр этого класса, его содержимое уже не может быть модифицировано.

Существует много способов создать объект String. Наиболее простой, если содержимое строки известно на этапе компиляции, – написать текст в кавычках:

String abc = "abc";

Можно использовать и различные варианты конструктора. Наиболее простой из них – конструктор, получающий на входе строковый литерал.

String s = new String("immutable");

На первый взгляд, эти варианты создания строк отличаются только синтаксисом. На самом же деле различие есть, хотя в большинстве случаев оно несущественно. Рассмотрим пример:

public class Test { public Test() { }

public static void main(String[] args) { Test t = new Test(); String s1 = "Hello world !!!"; String s2 = "Hello world !!!"; System.out.println("String`s equally = " + (s1.equals(s2))); System.out.println( "Strings are the same = " + (s1==s2)); } }

В результате на консоль будет выведено:

String`s equally = true Strings are the same = true

Теперь несколько модифицируем код:

public class Test { public Test() { } public static void main(String[] args) { Test t = new Test(); String s1 = "Hello world !!!"; String s2 = new String("Hello world !!!"); System.out.println("String`s equally = " + (s1.equals(s2))); System.out.println( "Strings are the same = " + (s1==s2)); } }

В результате на консоль будет выведено:

String`s equally = true Strings are the same = false

Почему результат изменился? Дело в том, что создание нового объекта – это одна из самых трудоемких процедур в Java. Поэтому компилятор стремится уменьшить их количество, если это не приводит к непредсказуемому поведению программы.

В примере объявляются две переменных, которые инициализируются одинаковым значением. Поскольку класс String неизменяемый, их значения всегда будут одинаковыми. Это позволяет компилятору завести скрытую вспомогательную текстовую переменную, которая будет хранить такое значение, а все остальные переменные будут ссылаться на него же, а не порождать новые объекты. В результате в первом варианте программы создается лишь один объект String. Для большинства операций это несущественная разница. Исключение составляют действия, которые привязаны к конкретному объекту, а не к его значению. Это метод equals, методы wait/notify.

Во втором варианте указано динамическое обращение к конструктору. В этом случае компилятор уже не имеет возможности заниматься оптимизацией и JVM во время исполнения программы действительно создаст второй объект с точно таким же значением. Что мы и видим по результату выполнения примера.

В Java для строк определен оператор +. При использовании этого оператора производится конкатенация строк. В классе String также определен метод:


public String concat(String s);

Он возвращает новый объект-строку, дополненный справа строкой s.

Рассмотрим другой пример.

public class Test { public static void main(String[] args) { Test t = new Test(); String s = " prefix !"; System.out.println(s); s = s.trim(); System.out.println(s); s = s.concat(" suffix"); System.out.println(s); } }

prefix ! prefix ! prefix ! suffix

В данном случае может сложиться впечатление, что строку (объект String, на который ссылается переменная s), можно изменять. В действительности это не так. В результате выполнения методов trim (отсечение пробелов в начале и конце строки) и concat создаются новые объекты-строки и ссылка s начинает указывать на новый объект-строку. Таким образом, меняется значение ссылки, объекты же неизменяемы.

Как уже отмечалось, строка состоит из двухбайтных Unicode-символов. Однако во многих случаях требуется работать со строкой как с набором байт (ввод/вывод, работа с базой данных и т.д.). Преобразование строки в последовательность байтов производится следующими методами:



  • byte[] getBytes() – возвращает последовательность байтов в кодировке, принятой по умолчанию (как правило, зависит от настроек операционной системы);




  • byte[] getBytes(String encoding) – возвращает последовательность байтов в указанной кодировке encoding.


Для выполнения обратной операции (преобразования байтов в строку) необходимо сконструировать новый объект-строку с помощью следующих методов:



  • String(byte[] bytes) – создает строку из последовательности байтов в кодировке, принятой по умолчанию;


  • String(byte[] bytes, String enc) – создает строку из последовательности байтов в указанной кодировке.



Содержание раздела