Как стать автором
Обновить

JDK 8 в примерах

Java *
Из песочницы
Недавно в Oracle блоге Brian Goetz опубликовал ссылку на презентацию с Devoxx talk on Language / Library / VM Co-Evolution in Java SE 8.
В статье я попытаюсь вкратце раскрыть основные проблемы, которые будут решены в восьмерке, а также пути их решения, которые были избраны компанией Oracle. Остальные аспекты можно посмотреть в оригинале.

Читайте дальше:
Расширение существующих API с обратной совместимостью;
Java становится еще более объектно-ориентированной;
Лямбда-выражения в Java;
Упрощение многопоточности.

Итак, что хочет сделать Oracle:

I. Расширение существующих API с обратной совместимостью.


Чтобы упростить всем джавистам жизнь, было решено расширить/дополнить JDK, а также дать возможность всем (в том числе существующим фреймворкам) дополнить свои API. При этом обязательным условием является сохранение работоспособности legacy-кода. Для этого ребята из Oracle сделали виртуальные методы расширения(Virtual extension methods).
Виртуальные методы расширения это методы, которые можно добавить в существующие интерфейсы и предоставить дефолтную реализацию этих методов, при этом классы-реализации не потребуют перекомпиляции и будут работать как и работали раньше. Получаем сохранение работоспособности существующих API с одной стороны и возможность расширить функционал с другой.

Пример — Iterator и UnsupportedOperationException.

Все мы знаем метод remove интерфейса Iterator. В javadoc’е сказано, что если реализация итератора не поддерживает метод remove, то она может выбросить UnsupportedOperationException. Согласитесь, криво. Если я не собираюсь реализовывать метод, то зачем мне определять его и выбрасывать exception?

Решение:

interface Iterator<T> {
		  boolean  hasNext();
		  T next();
		  void remove() 
		  default { throw new UnsupportedOperationException(); };
		}
		

Здесь определяется дефолтная реализация для метода remove. Теперь классы-реализации не обязаны предоставлять реализацию этого метода.

Пример – итерация по списку.

Допустим, есть код, который определяет наибольший балл среди студентов за 2011 год:

		  List<Student> students = ...
		  double highestScore = 0.0;
		  for (Student s: students) {
		    if (s.getGradYear() == 2011) {
		      if (s.getScore() > highestScore) {
		        highestScore = s.score;
		      }
		    }
		  }
		

На первый взгляд довольно сносный код. Но он не является объектно-ориентированным. Сама итерация по списку происходит в цикле ‘for’ в клиентском коде, который использует этот список. Можно добавить виртуальные методы в коллекции и переписать этот код используя уже объектно-ориентированный подход и «внутреннюю» итерацию.

		  SomeCoolList<Student> students = ...
		  double highestScore = 
		    students.filter(new Predicate<Student>() {
		      public boolean op(Student s) {
		        return s.getGradYear() == 2011;
		      }
		    }).map(new Mapper<Student, Double>() {
		       public Double extract(Student s) {
		         return s.getScore();
		       }
		    }).max();
		

Здесь уже итерацию выполняет класс SomeCoolList. Но согласитесь, очень уж это громоздко и многословно. И тут на помощь приходят lambda expression.

Решение:


		  SomeCoolList<Student> students = ...
		  double highestScore = 
		    students.filter(Student s -> s.getGradYear() == 2011)
		            .map(Student s -> s.getScore())
		            .max();
		

Данный подход имеет еще одно преимущество – в нем проще распаралелить выполнение, поскольку проход по коллекции выполняется самой коллекцией.

II. Упрощение многопоточности


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

		  SomeCoolList<Student> students = ...
		  double highestScore = 
		    students.parallel()
		            .filter(Student s -> s.getGradYear() == 2011)
		            .map(Student s -> s.getScore())
		            .max();
		


На этом основные мажорные фичи восьмерки заканчиваются.

Также напомню, что скачать JDK Standard Edition 8 Developer Preview with Lambda Support можно здесь.
Теги:
Хабы:
Всего голосов 59: ↑52 и ↓7 +45
Просмотры 16K
Комментарии Комментарии 66