Я начал писать пост в блоге о том, что нового появилось в следующем выпуске Java8 , и подумал, что начну с того, что быстро оглянемся на то, что Java7 принес нам.
Java7 был выпущен еще в июле 2011 года и был описан как «скорее эволюционный, чем революционный».
«Есть некоторые значительные улучшения, но нет действительно потрясающих или новаторских функций». — Oracle главный архитектор Java Марк Рейнхольд
Например, в нем не было много раскрученных лямбда-выражений. Тем не менее, он внес много других полезных дополнений в язык Java. Вы можете увидеть больше на http://docs.oracle.com/javase/7/docs/ или прочитать мое резюме.
Основные моменты Java7 включены:
- Проектная монета
- Строки в выключателе
- оператор проб с ресурсами
- Мульти-улов и более точное отбрасывание
- Алмазный оператор
- Двоичные целочисленные литералы
- Подчеркивает в числовых литералах
- Новые функции ввода / вывода
- Утилиты Fork & Join / Concurrency
Монета проекта
Монета проекта, каламбур на «мелочь», содержит несколько незначительных, но полезных функций, в том числе:
Строки в выключателе
До Java 7 операторы switch работали либо с примитивными типами, либо с перечисляемыми типами. В Java 7 появился другой тип, который мы можем использовать в операторах Switch: тип String
. Скажем, у нас есть требование для обработки сделки на основе поля статуса String. До сих пор мы делали это, используя операторы if-else.
01
02
03
04
05
06
07
08
09
10
|
private void processTrade_UsingIfs(Trade t) { String status = t.getStatus(); if (status.equalsIgnoreCase( "New" )) { setupNewTrade(t); } else if (status.equalsIgnoreCase( "Execute" )) { executeTrade(t); } else if (status.equalsIgnoreCase( "Pending" )) { processTrade(t); } } |
В Java7 мы можем сделать то же самое, используя оператор switch:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
public void processTrade_UsingSwitch(Trade t) { String status = t.getStatus(); switch (status) { case "New" : setupNewTrade(t); break ; case "Execute" : executeTrade(t); break ; case "Pending" : processTrade(t); break ; default : break ; } } |
Автоматическое управление ресурсами в try-Statement
Теперь вы можете объявить ресурс в блоке try, который будет автоматически закрыт. например, раньше приходилось делать:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
public void oldTry() { FileReader fileReader = null ; BufferedReader inputStream = null ; try { fileReader = new FileReader( "java7.txt" ); inputStream = new BufferedReader(fileReader); String line = inputStream.readLine(); System.out.println(line); } catch (IOException e) { //typically log or rethrow } finally { //all resources need to be manually closed try { fileReader.close(); inputStream.close(); } catch (IOException e) { //typically ignore } } } |
Однако теперь в Java 7 оператор try-with-resources гарантирует, что каждый ресурс закрыт в конце оператора.
01
02
03
04
05
06
07
08
09
10
11
12
13
|
public void newTry() { try ( FileReader fileReader = new FileReader( "java7.txt" ); BufferedReader inputStream = new BufferedReader(fileReader) ) { String line = inputStream.readLine(); System.out.println(line); } catch (IOException e) { //typically log or rethrow } //no finally block to close resources required } |
Объявление ресурсов отображается в скобках сразу после ключевого слова try.
Любой объект, который реализует java.lang.AutoCloseable, который включает все объекты, которые реализуют java.io.Closeable, может использоваться в качестве ресурса. Ресурсы будут закрыты независимо от того, завершается ли оператор try нормально или внезапно
Мульти-улов и более точное отбрасывание
Мульти поймать
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
public void oldMultiCatch() { try { methodThatThrowsThreeExceptions(); } catch (ExceptionOne e) { // log and deal with ExceptionOne } catch (ExceptionTwo e) { // log and deal with ExceptionTwo } catch (ExceptionThree e) { // log and deal with ExceptionThree } } public void newMultiCatch() { try { methodThatThrowsThreeExceptions(); } catch (ExceptionOne | ExceptionTwo | ExceptionThree e) { // log and deal with all Exceptions } } public void newMultiMultiCatch() { try { methodThatThrowsThreeExceptions(); } catch (ExceptionOne e) { // log and deal with ExceptionOne } catch (ExceptionTwo | ExceptionThree e) { // log and deal with ExceptionTwo and ExceptionThree } } |
Более точный бросок
Компилятор Java SE 7 выполняет более точный анализ переброшенных исключений, позволяя вам указать более конкретные типы исключений в предложении throws объявления метода, чем те, которые используются в catch / throws тела метода.
Раньше мы должны были сделать что-то вроде этого:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
static class FirstException extends Exception { } static class SecondException extends Exception { } public void rethrowException_PreJava7(String exceptionName) throws Exception { try { if (exceptionName.equals( "First" )) { throw new FirstException(); } else { throw new SecondException(); } } catch (Exception e) { throw e; } } |
Обратите внимание, как мы должны были объявить более общее исключение в нашем предложении throws. В Java7 мы можем изменить это на:
01
02
03
04
05
06
07
08
09
10
11
|
public void rethrowException_PostJava7(String exceptionName) throws FirstException, SecondException { try { if (exceptionName.equals( "First" )) { throw new FirstException(); } else { throw new SecondException(); } } catch (Exception e) { throw e; } } |
Алмазный оператор
Оператор diamond упрощает вызовы конструктора, включая дженерики. Допустим, вы хотите создать карту идентификаторов строк для торговли объектами. Старый способ был бы:
1
|
Map<String, Trade> trades = new TreeMap<String, Trade>(); |
Но правая часть кажется немного избыточной. Может ли компилятор вывести типы, посмотрев на левую декларацию? В Java7 это может, и код становится:
1
|
Map<String, Trade> trades = new TreeMap<>(); |
Это приятное, но незначительное удобство — с ним уже можно было справиться, используя библиотеку Guava . Например:
1
|
Map<String, Trade> trades = Maps.newTreeMap(); |
Двоичные целочисленные литералы
Полезно, если вы имеете дело с двоичным кодом в вашем коде. Например, теперь вы можете сделать:
1
|
int three = 0b101; |
Обратите внимание на префикс 0b (или 0B), чтобы идентифицировать число как двоичный литерал.
Разрешение подчеркивания в числовых литералах
Я не думаю, что это слишком важно, но может быть полезно в некоторых обстоятельствах. например:
1
|
long creditCardNumber = 1234_5678_9012_3456L; |
Утилиты Fork & Join / Concurrency (JSR 166)
Инфраструктура Fork / Join фокусируется на использовании всех ресурсов обработки, доступных на машине, для повышения производительности приложений. Он предназначен для работы, которая может быть рекурсивно разбита на более мелкие части (алгоритмы «разделяй и властвуй»).
Резюме:
- Fork / Join Framework: упрощает параллельное программирование на Java
- Предназначен для многопроцессорных систем (на самом деле сегодня это практически все оборудование)
Используйте в ситуациях, когда:
- пакет работы может быть разбит на меньшие рекурсивные вызовы.
- также использует алгоритм кражи работы, при котором потоки без работы могут украсть доступную работу из других занятых потоков
Автор Дуг Ли:
- Создатель пакета oswego (стал java.util.concurrent)
- Участник Java-параллелизма на практике
Краткая история
Java 1.4 и более notifyAll()
: разработка параллельных классов была очень трудной — предоставляемые низкоуровневые примитивы параллелизма ( synchronized
, volatile
, wait()
, notifyAll()
и notifyAll()
) были трудны для правильного использования, а ошибки, возникающие при использовании этих средств, затруднялись обнаружить и отладить
Java 5: включен новый пакет утилит параллелизма
Структура планирования задач — платформа Executor
Исполнитель: объект, который выполняет представленные выполняемые задачи.
ExecutorService: Executor
который предоставляет методы, которые создают Future
который представляет (пока не завершено) результат асинхронного вычисления.
Java 7: ForkJoinPool: новый тип ExecutorService, which
позволяет executes ForkJoinTasks:
одновременное выполнение обработки и рекурсивно executes ForkJoinTasks:
потоковый объект, который имеет гораздо меньший вес, чем обычный поток. Огромное количество задач и подзадач может быть размещено небольшим количеством реальных потоков в ForkJoinPool.
Новый ForkJoinPool использует алгоритм «разделяй и властвуй».
Псевдокод (из статьи Дуга Ли на эту тему):
1
2
3
4
5
6
7
8
9
|
Result doWork(Work work) { if (work is small) { process the work } else { split up work invoke framework to solve both parts } } |
Резюме
- приятно видеть дальнейшее продвижение в Java в пространстве параллелизма, чтобы использовать все преимущества, которые мы получили в Java 5
- Потенциальные возможности использования этой структуры ограничены и требуют довольно узкого охвата проблемы.
Новые функции ввода / вывода
Java7 представила новую библиотеку файлового ввода / вывода для повышения независимости платформы и добавления поддержки метаданных и символических ссылок. Новые пакеты — это java.nio.file и java.nio.file.attribute. Основные новые классы:
- Путь : «программное представление пути в файловой системе». Вероятно, это новый класс (интерфейс), который разработчики будут использовать чаще всего. Файл, указанный по пути, не должен существовать. Для всех практических целей вы можете подумать о замене java.io.File на java. io.Path. Он включает в себя различные методы, которые можно использовать для получения информации о пути, включая создание, преобразование и сравнение путей.
- Файлы : класс Files предлагает большое количество статических методов для операций с файлами, например, для чтения, записи и управления файлами и каталогами. Методы Files работают с экземплярами объектов Path.
Это оно! Краткое изложение того, что дала нам Java7. См. Мой следующий пост в блоге для обзора некоторых новых функций в Java8.