// Без ромбовидного оператора
List<String> list = new ArrayList<String>();
Map<Reference<Object>, Map<Integer, List<String>>> map =
····new HashMap<Reference<Object>, Map<Integer, List<String>>>();
// C ромбовидным оператором
List<String> list = new ArrayList<>();
Map<Reference<Object>, Map<Integer, List<String>>> map = new HashMap<>();
Конструкция try-with-resources
В некоторых Java API закрытием ресурсов необходимо управлять вручную, обычно с помощью метода close в блоке finally. Это касается ресурсов, управляемых операционной системой, например файлов, сокетов или соединений интерфейса JDBC. Листинг 1.8 показывает, как необходимо ставить закрывающий код в блоке finally с обработкой исключений, но удобочитаемость кода из-за этого снижается.
try {
··InputStream input = new FileInputStream(in.txt);
··try {
····OutputStream output = new FileOutputStream(out.txt);
····try {
······byte[] buf = new byte[1024];
······int len;
······while ((len = input.read(buf)) >= 0)
······output.write(buf, 0, len);
····} finally {
······output.close();
····}
··} finally {
····input.close();
··}
} catch (IOException e) {
··e.printStrackTrace();
}
Конструкция try-with-resources решает проблему читаемости с помощью нового, более простого синтаксиса. Это позволяет ресурсам в блоке try автоматически высвобождаться в его конце. Нотация, описанная в листинге 1.9, может использоваться для любого класса, реализующего новый интерфейс java.lang.AutoCloseable. Сейчас он реализуется множеством классов (InputStream, OutputStream, JarFile, Reader, Writer, Socket, ZipFile) и интерфейсов (java.sql.ResultSet).
try (InputStream input = new FileInputStream(in.txt);
·····OutputStream output = new FileOutputStream(out.txt)) {
··byte[] buf = new byte[1024];
··int len;
··while ((len = input.read(buf)) >= 0)
····output.write(buf, 0, len);
} catch (IOException e) {
··e.printStrackTrace();
}
Multicatch-исключения
До появления Java SE 6 блок захвата мог обрабатывать только одно исключение в каждый момент времени. Поэтому приходилось накапливать несколько исключений, чтобы потом применить нужное действие для обработки исключений каждого типа. И как показано в листинге 1.10, для каждого исключения зачастую необходимо выполнять одно и то же действие.
try {
··// Какое-либо действие
} catch(SAXException e) {
··e.printStackTrace();
} catch(IOException e) {
··e.printStackTrace();
} catch(ParserConfigurationException e) {
··e.printStackTrace();
}
Если разные исключения требуют одинаковой обработки, в Java SE 7 вы можете добавить столько типов исключений, сколько нужно, разделив их прямым слешем, как показано в листинге 1.11.
try {
··// Какое-либо действие
} catch(SAXException | IOException | ParserConfigurationException e) {
··e.printStackTrace();
}
NIO.2
Если вам, как и многим Java-разработчикам, с трудом удается читать или записывать некоторые файлы, вы оцените новую возможность Java SE 7: пакет ввода/вывода java.nio. Этот пакет, обладающий более выразительным синтаксисом, призван заменить существующий пакет java.io, чтобы обеспечить:
• более аккуратную обработку исключений;
• полный доступ к файловой системе с новыми возможностями (поддержка атрибутов конкретной операционной системы, символических ссылок и т. д.);
• добавление понятий FileSystem и FileStore (например, возможность разметки диска);
• вспомогательные методы (перемещение/копирование файлов, чтение/запись бинарных или текстовых файлов, путей, каталогов и т. д.).
В листинге 1.12 показан новый интерфейс java.nio.file.Path (используется для определения файла или каталога в файловой системе), а также утилитный класс java.nio.file.Files (применяется для получения информации о файле или манипулирования им). Начиная с Java SE 7 рекомендуется использовать новый NIO.2, даже пока старый пакет java.io не вышел из употребления. В листинге 1.12 код получает информацию о файле source.txt, копирует его в файл dest.txt, отображает его содержимое и удаляет его.