Статьи

Как проект янтаря революционизирует Java

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

Ранее на этой неделе Брайан Гетц, архитектор языка Java в Oracle, официально объявил о проекте Amber, и я не мог быть более взволнован этим! Он продолжит то, что начал Java 8, и сделает Java гораздо менее многословным и еще более увлекательным языком. Вывод типов, чрезвычайно упрощенные классы данных, сопоставление с образцами … все это в последние месяцы бурлило, но приятно видеть, что оно вышло на официальные треки.

(Хотя это может быть новым для Java, разработчики, не являющиеся Java, могут насмехаться и смотреть на нас свысока с такими комментариями, как «мы используем это уже десять лет». Что ж, хорошо для вас, но у нас нет причин идти на дождь парад так стфу!)

Революционные Борцы

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

(Если вам интересно посмотреть, как эти предложения и типы значений могут играть вместе, взгляните на то , как может выглядеть будущее Java ).

Вывод типа локальной переменной

Java сделала вывод типов начиная с Java 5 (для свидетелей типов в универсальных методах), и механизм был расширен в Java 7 (оператор diamond), 8 (типы параметров лямбда) и 9 (diamond в анонимных классах). В Project Amber его планируется распространить на объявления типов локальных (!) Переменных:

// now URL url = new URL("...") URLConnectoin conn = url.openConnection(); Reader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); // maybe in the future var url = new URL("...") var conn = url.openConnection(); var reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); 

Здесь типы url , conn и reader совершенно очевидны. Как следствие, компилятор может вывести их, что делает ненужным их указание.

Обратите внимание, что вывод типа не является динамической типизацией — это все еще сильная типизация, просто с меньшим набором текста (каламбур Брайана, предположительно предназначенный). Информация о типе будет по-прежнему попадать в байт-код, и IDE также смогут их показывать — просто нам больше не нужно ее выписывать.

Для получения дополнительной информации посмотрите на JEP 286 .

Расширенные Enums

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

 // now public enum FavoriteNumber { INTEGER(42), FLOAT(3.14); // wouldn't it be nice if this were more specific than Number? public final Number favorite; FavoriteNumber(Number favorite) { this.favorite = favorite; } } 

Проект Amber считает, что перечисления должны иметь параметры типа:

 // maybe in the future public class FavoriteNumber<T extends Number> { INTEGER<Interger>(42), FLOAT<Float>(3.14); // wouldn't it be nice if this were more specific than Number? public final T favorite; FavoriteNumber(T favorite) { this.favorite = favorite; } } 

И замечательно, что компилятор выполнит точную проверку типов и узнает, какие универсальные типы имеет конкретный экземпляр enum:

 // maybe in the future float favorite = FavoriteNumber.FLOAT.favorite; 

Для получения дополнительной информации взгляните на JEP 301 .

Лямбда остатки

Отличное имя, а? Это пара небольших улучшений лямбда-выражений и ссылок на методы. Во-первых, компилятор будет лучше выбирать цель для лямбда-выражения или ссылки на метод в ситуациях, когда ему нужно выбрать одну из нескольких перегрузок:

 // now; compile error: "ambiguous method call" method(s -> false) private void method(Predicate<String> p) { /* ... */ } private void method(Function<String, String> f) { /* ... */ } 

Странно, что компилятор считает, что это неоднозначно, потому что для нас это не так. Когда лямбда-остатки реализованы, компилятор соглашается.

Java 8 устарела как имя переменной и запретила его как имя лямбда-параметра. В Java 9 также запрещено использовать его в качестве имен переменных, поэтому он может получить специальное значение, а именно помечать неиспользуемые лямбда-параметры (да, более одного в одном выражении):

 // maybe in the future // ignore the parameter marked as `_` BiFunction<Integer, String, String> f3 = (i, _) -> String.valueOf(i); // if there were a TriFunction: BiFunction<Integer, String, String, String> f3 = (i, _, _) -> String.valueOf(i); 

Наконец, Project Amber исследует возможность позволить лямбда-параметрам скрывать переменные во внешней области видимости. Это сделало бы их именование немного легче, потому что в его нынешнем виде это может быть немного обременительно:

 private Map<String, Integer> wordLengthCache; // now public int computeLength(String word) { // can't reuse `word` in lambda, so... maybe `w`? wordLengthCache.computeIfAbsent(word, w -> w.length()); } // maybe in the future public int computeLength(String word) { // can't reuse `word` in lambda, so... maybe `w`? wordLengthCache.computeIfAbsent(word, word -> word.length()); } 

Для получения дополнительной информации взгляните на JEP 302 .

Классы данных

Мы все создали множество простых классов-держателей данных, для которых требовались десятки строк кода для полей, конструктора, методов доступа, equals , hashCode , toString . В то время как IDE успешно генерируют все это, что делает его ввод ненужным даже сегодня, это все еще код, который необходимо понять (конструктор выполняет какую-либо проверку?) И поддерживать его (лучше не забывать добавлять это новое поле в equals).

В агрессивном шаге по сокращению шаблонов, компилятор может генерировать все эти вещи на лету без нас, чтобы согнуть палец!

 // maybe in the future public class User(String firstName, String lastName, DateTime birthday) { } 

Мы можем получить все остальное, что я упомянул выше, бесплатно, и нам нужно только реализовать то, что является нестандартным (возможно, у пользователей есть идентификатор, который сам определяет равенство, поэтому мы бы хотели, чтобы была реализована equals реализация). Избавление от всего этого кода было бы большим стимулом для удобства обслуживания!

(Для этого предложения пока нет JEP, но Эмбер примет его, как только оно будет.)

Сопоставление с образцом

Текущий оператор switch Java довольно слабый. Вы можете использовать его для примитивов, перечислений и строк, но это все. Если вы хотите сделать что-то более сложное, вы либо прибегаете к цепочкам ifelseif либо, если вы не можете выбросить из головы книгу «Банды четырех», — шаблон посетителей .

Проект Amber исследует то, что обычно называют сопоставлением с образцом. Он работает со всеми типами, может иметь более сложные условия, чем проверки на равенство, и является выражением, означающим, что ему может быть присвоено значение. Вот пример, который Брайан показал в Devoxx Belgium несколько месяцев назад:

 // maybe in the future String formatted = switch (constant) { case Integer i -> String.format("int %d", i); case Byte b: //... case Long l: // ... // ... default: formatted = "unknown" } 

(Для этого предложения пока нет JEP, но Эмбер примет его, как только оно будет.)

Проект Янтарь. Потому что, почему бы и нет?

Проект Янтарь

Теперь, когда мы знаем, какие функции в настоящее время изучаются в рамках проекта Amber, пришло время более подробно рассмотреть сам проект. В приветственном письме описывается «инкубационная площадка для отдельных JEP, ориентированных на производительность, на языке Java». Скажем в общих чертах, его область действия определяется как любой JEP, который группа экспертов находит интересным, и согласуется с общим утверждением миссии:

Чтобы быть принятым к рассмотрению Проектом Янтарь, функция должна быть сначала описана JEP . Это означает, что здесь не место обсуждать идеи случайных языковых особенностей (для этого все еще доступен весь интернет); давайте сосредоточимся на специфических особенностях, которые были приняты.

Прочтите эту почту, чтобы получить ссылки на JEP, списки рассылки и репозиторий.

Дата выхода

Естественный вопрос: когда проект будет отправлен? Когда вы сможете начать писать этот потрясающий код, который я обещаю продолжать? Самый ответственный ответ — никто не знает.

Оставляя в стороне ответственность, мы можем немного спекулировать. Проект Lambda , который принес лямбда-выражения и потоки, занял чуть более четырех лет с момента его создания в декабре 2009 года до его дебютного релиза в марте 2014 года. Project Jigsaw , печально известный своими задержками, стартовал годом ранее, в декабре 2008 года, и только отправляется сейчас, что занимает почти девять лет. Имейте в виду, однако, что Oracle приобрела Sun в 2010 году, и я могу только предположить, что переходный период отрицательно сказался на инженерных разработках. Кроме того, мне кажется, что оба проекта являются значительно более сложными и монолитными, чем Amber (хотя оба трудно судить извне).

Проект «Янтарь» — это скорее крыша для различных изменений, которые двигают язык в общем направлении, но, возможно, его не придется отправлять сразу, чтобы иметь смысл. При таком предположении и предположении времени разработки проекта, основанного на Lambda и Jigsaw, представляется вероятным, что некоторые изменения внесут его в Java 10.

Прежде чем спросить: никто не знает, когда 10 выйдет! Опять некоторые предположения, еще в 2012 году Марк Рейнхольд, главный архитектор Java Platform Group, предложил двухлетний цикл выпуска, который из-за задержек стал более трехлетним циклом. Экстраполируя будущее из двух точек данных (к счастью, я не привязан к научным стандартам), 2020 год выглядит как хорошее предположение.

Имейте в виду, однако, что проект Valhalla начался в июле 2014 года и взял на себя огромные обязательства по внедрению общих специализаций и типов стоимости . Он еще не предназначен для какого-либо релиза, но похоже, что он входит в десятый период времени. Если это так, он может очень хорошо отложить релиз из-за его сложности.

Итак, суть в том, что никто не знает. Если бы мне пришлось ставить деньги, я бы поставил их на 2020 год. Пальцы скрещены.

Об этом имени …

Ах да, почему он называется Project Amber ? Потому что это блестяще? Потому что это сохраняет мертвые вещи? Я не знаю.

Вместо того, чтобы тратить ненужные циклы на размышления об этом, я решил спросить самого Брайана, но он был либо очень скрытным, либо очень открытым:

Однако он сделал предложение, чтобы мы пришли с объяснением, так почему бы и нет?

Итак, вот в чем дело: вы оставляете комментарий или твит (не забудьте упомянуть меня) со своим объяснением, почему он может называться Project Amber, и я позволю Брайану и его команде выбрать тот, который им нравится больше всего (крайний срок: 26 марта) , Чтобы сделать это настоящим соревнованием, победитель получает копию моей будущей книги о модульной системе Java 9 .

Так что ты думаешь? Почему янтарь?

Две недели спустя…

Материалы

Спасибо всем за участие. Ваши идеи:

Каждый раз, когда люди упоминают «Янтарь», я вспоминаю эту часть «Парка Юрского периода», ха-ха, возможно, все эти новые функции происходят из ДНК старых программистов, но со свежими идеями. ( Хуан Морено )

Монета проекта -> Монета проекта фрезерования -> Пока мы копаемся в сундуке с сокровищами, мы также обнаруживаем полудрагоценный камень -> Янтарь ( Андреас Аронссон )

Amber просто содержит все, что мы хотели для этого проекта:
Сначала каменистость, чтобы заинтересовать тебя,
затем импульс, чтобы вы продолжали,
б блеск везде,
поощряя вас не только к воле
но для развития вашего кода.
( матамеко )

Мы не хотели, чтобы Java стала окаменелой, но мы также хотим, чтобы функции, которые мы добавили, заставили язык снова ослепить! ( Джим Бетанкур )

Я предполагаю, что у них только что был конкурс имен, и в этом нет логики. Ницца. Блестящая. Короткий. Нет проблем с другими культурами и языками. ( Юкка Никки )

Это может быть также имя дочери ведущего проекта. ( Юкка Никки )

И победителем становится…

Квакерони ( отобранный самим Брайаном Гетцем ) с:

Поздравляем! 😀 О ваших хороших детективных навыках, а также о цене . Хотя объяснение определенно интригует, у Брайана есть еще одно:

Итак, теперь мы знаем, почему проект, революционизирующий Java, называется Amber….