Программирование на Java
Шрифт:
Для выполнения обратной операции (преобразования байтов в строку) необходимо сконструировать новый объект-строку с помощью следующих методов:
* String(byte[] bytes) – создает строку из последовательности байтов в кодировке, принятой по умолчанию;
* String(byte[] bytes, String enc) – создает строку из последовательности байтов в указанной кодировке.
StringBuffer
Этот класс используется для создания и модификации строковых
Рассмотрим наиболее часто используемые конструкторы класса StringBuffer:
* StringBuffer – создает пустой StringBuffer ;
* StringBuffer(String s) – буфер заполняется указанным значением s ;
* StringBuffer(int capacity) – создает экземпляр класса StringBuffer с указанным размером (длина char[] ). Задание размера не означает, что нельзя будет оперировать строками с большей длиной, чем указано в конструкторе. На самом деле этим гарантируется, что при работе со строками меньшей длины дополнительное выделение памяти не потребуется.
Разница между String и StringBuffer может быть продемонстрирована на следующем примере:
public class Test {
public static void main(String[] args) {
Test t = new Test;
String s = new String("ssssss");
StringBuffer sb =
new StringBuffer("bbbbbb");
s.concat("-aaa");
sb.append("-aaa");
System.out.println(s);
System.out.println(sb);
}
}
В результате на экран будет выведено следующее:
ssssss
bbbbbb-aaa
В данном примере можно заметить, что объект String остался неизменным, а объект StringBuffer изменился.
Основные методы, используемые для модификации StringBuffer, это:
* public StringBuffer append(String str) – добавляет переданную строку str в буфер;
* public StringBuffer insert(int offset, String str) – вставка строки, начиная с позиции offset (пропустив offset символов).
Стоит обратить внимание, что оба метода имеют варианты, принимающие в качестве параметров различные примитивные типы Java вместо String. При использовании этих методов аргумент предварительно приводится к строке (с помощью String.valueOf ).
Еще один важный момент, связанный с этими методами, – они возвращают сам объект, у которого вызываются. Благодаря этому, возможно их использование в цепочке. Например:
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("abc");
String str = sb.append("e").insert(4,
"f").insert(3,"d").toString;
System.out.println(str);
}
В результате на экран будет выведено:
abcdef
При
public class Test {
public static void main(String[] args) {
Test t = new Test;
StringBuffer sb = new StringBuffer("aaa");
System.out.println("Before = " + sb);
t.doTest(sb);
System.out.println("After = " + sb);
}
void doTest(StringBuffer theSb) {
theSb.append("-bbb");
}
}
В результате на экран будет выведено следующее:
Before = aaa
After = aaa-bbb
Поскольку все объекты передаются по ссылке, в методе doTest, при выполнении операций с theSB, будет модифицирован объект, на который ссылается sb.
Системные классы
Следующие классы, которые будут рассмотрены, обеспечивают взаимодействие с внутренними механизмами JVM и средой исполнения приложения:
* ClassLoader – загрузчик классов; отвечает за загрузку описания классов в память JVM;
* SecurityManager – менеджер безопасности; содержит различные методы проверки допустимости запрашиваемой операции;
* System – содержит набор полезных статических полей и методов;
* Runtime – позволяет приложению взаимодействовать со средой исполнения;
* Process – представляет интерфейс для взаимодействия с внешней программой, запущенной при помощи Runtime.
ClassLoader
Это абстрактный класс, ответственный за загрузку типов. По имени класса или интерфейса он находит и загружает в память данные, которые составляют определение типа. Обычно для этого используется простое правило: название типа преобразуется в название class -файла, из которого и считывается вся необходимая информация.
Каждый объект Class содержит ссылку на объект ClassLoader, с помощью которого он был загружен.
Для добавления альтернативного способа загрузки классов можно реализовать свой загрузчик, унаследовав его от ClassLoader. Например, описание класса может загружаться через сетевое соединение. Метод defineClass преобразует массив байт в экземпляр класса Class. С помощью метода newInstance могут быть получены экземпляры такого класса. В результате загруженный класс становится полноценной частью исполняемого Java-приложения.
Для иллюстрации приведем пример, как может выглядеть простая реализация загрузчика классов, использующего сетевое соединение:
class NetworkClassLoader extends ClassLoader {
String host; int port;
public NetworkClassLoader(String host, int port) {
this.host = host; this.port = port;
}
public Class findClass(String className) {
byte[] bytes = loadClassData(className);
return defineClass(className, bytes, 0,
bytes.length);