«Жизнь после Java 10»: какие изменения принесет Java 11

    Буквально недавно, в конце марта, вышел Java 10. Но в связи с тем, что компания Oracle внесла изменения в релизный цикл (новый релиз каждые полгода), к выходу готовится 11-я версия.

    Запуск намечен на сентябрь 2018-го. Мы предлагаем взглянуть на некоторые из грядущих обновлений, о которых известно на сегодняшний день.


    / фото Markus Spiske PD

    Java 10: краткая сводка


    Нововведениями десятой версии стали: локальный вывод типов с помощью var, улучшения в процессах «сборки мусора» и возможность использовать Graal как основной JIT-компилятор.

    Локальный вывод типов с помощью var просили многие разработчики. Теперь можно не вводить типы два раза подряд: сперва для объявления переменной, а затем для конструктора, идущего следом.

    var list = new ArrayList<String>();  // infers ArrayList<String>
    var stream = list.stream();          // infers Stream<String>
    

    Однако решение ввести var получило неоднозначные отзывы участников сообщества. Кто-то высказывался за нововведение и говорил, что дедупликация повышает читабельность кода. Но были и те, кто отмечал, что теперь ряд типов переменных (например, connection) не будут очевидными. И хотя IDE теперь смогут показывать их по требованию, в других средах будут возникать проблемы.

    Для улучшенной сборки мусора в десятый релиз были включены сразу два изменения: JEP 304 и JEP 307. JEP 304 улучшил изоляцию кода от различных сборщиков мусора за счет нового интерфейса GC, что позволило быстрее интегрировать сторонние сборщики. JEP 307 же дал возможность «собирать мусор» в несколько потоков.

    Что касается нового JIT-компилятора, то он направлен на улучшение производительности JVM. Прежняя версия JVM была написана на C++, однако в рамках проекта Metropolis большую часть JVM перепишут на Java. Экспериментальный компилятор является первым шагом на пути к этой цели.


    / фото Betsy Weber CC

    Возможные нововведения в Java 11


    В начале осени разработчики планируют представить Java 11. И о ряде функций, которые могут стать частью релиза, известно уже сегодня. В сети даже идет бурное обсуждение предложенных изменений.

    Часть разработчиков недовольна тем, как быстро меняется язык. Один из резидентов Hacker News сказал: «Java превращается в совершенно новый язык. Одна из причин, почему я раньше использовал Java — это обратная совместимость. Если придется учить новый язык программирования каждые 6 месяцев, я выучу что-нибудь другое».

    Но есть и те, кто отмечает, что Java наконец-то обзаводится функциями, которых ему не хватало, и которые уже давно были реализованы в других ЯП. Еще один пользователь HN пишет: «Я не использовал Java с начала нулевых и удивлен, что они так долго вводят фичи, которые давно существуют в других языках». Вот некоторые из них.

    Изменения в локальном выводе типов

    Java 10 уже предоставил возможность использовать var для обозначения типа локальных переменных, перекладывая эту задачу на плечи компилятора. Однако Java 11 идет дальше и делает так, что var можно использовать при объявлении формальных параметров неявно типизированных лямбда-выражений.

    За подробным руководством о том, когда и как использовать var, можно обратиться к этой статье на OpenJDK.

    Добавление необработанных строковых литералов

    Это еще одно дополнение, над которым сейчас ведется работа. В необработанной строке каждый символ читается «как есть», включая символы разрыва. Например, такой строкой может быть разметка HTML или SQL-запрос:

    String html = "<html>\n" +
                  "  <body>\n" +
                  "    <p>Hello World.</p>\n" +
                  "  </body>\n" +
                  "</html>\n";
    

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

    String html = `<html>
                     <body>
                       <p>Hello World.</p>
                     </body>
                   </html>
                  `;
    

    Для обозначения необработанной строки используется обратный апостроф (`). Если вам нужно прописать апостроф внутри самой строки, то в этом случае для маркировки её границ используются двойные (или тройные, четверные и т. д.) обратные апострофы:

    String str = ```This is a raw `string` with ``backticks`` inside```;

    Появятся switch-выражения

    Сейчас оформление switch выполняется следующим образом:

    int val;
    switch (str) {
      case "foo": val = 1; break;
      case "bar": val = 2; break;
      case "baz": val = 3; break;
      default: val = -1;
    }
    

    С появлением switch-выражений, конструкция сократится:

    int val = switch (str) {
      case "foo": break 1;
      case "bar": break 2;
      case "baz": break 3;
      default: break -1;
    }
    

    При этом если в case встречается только break, возможно использовать упрощенную нотацию:

    int val = switch (str) {
      case "foo" -> 1;
      case "bar" -> 2;
      case "baz" -> 3;
      default -> -1;
    }
    

    Добавление switch expressions — это шаг вперед на пути к появлению метода сопоставления с образцом.

    Помимо отмеченных выше, Java может получить и другие изменения. Например, поддержку типов значений или переменных типа в enum. Эти обновления не обязательно войдут в состав Java 11, но, вероятно, ожидать их можно уже в ближайшем будущем.



    P.S. О чем еще мы пишем в Первом блоге о корпоративном IaaS:


    P.P.S. Несколько материалов из нашего блога на Хабре:

    ИТ-ГРАД 376,47
    vmware iaas provider
    Поделиться публикацией
    Комментарии 37
    • –4
      новый релиз каждые полгода

      Если раньше новая версия Java была событием, то теперь это станет полугодовым отчётом работы малоинтересного конвейера.

      • +5
        Ну а как ещё c# догнать-то…
        • +1
          C# существует давно и что-то раньше никто не делал от этого релизы чаще. Мне кажется, виной тут служит набирающие популярность языки на JVM, такие как Groovy, Scala и прежде всего Kotlin.
          • +2
            Скорее, экспансия C# на другие платформы, помимо Windows.
            • +4
              На полях, отличных от Windows, позиции C# пока не так сильны. Не хватает инфраструктуры, фреймворков, инструменты «застряли» в винде и т.д. Между тем, есть Котлин, который по функционалу точно не уступает C# (а в чем-то лучше), и на котором можно использовать все возможности богатого java мира.
          • +1
            Помнится какая-то софтина под вантуз сказала «э, не я не буду устанавливаться т.к. мне надо net framework 4.5.2, а установлен устаревший 4.5!». Ну куда уж жабке до такого великолепия? :)
            • +3
              А у меня была программа, которая требовала Java 7, а у меня стояла Java 6… Ну не смешно же.
              • 0
                Между релизами j6 и j7 сколько времени прошло? А сколько между n4.5 и n4.5.2? А ещё у вас _в порядке вещей_ требовать версию net framework предыдущего поколения, типа 3.5 много, дай 2.0
                • +3
                  Ну вот поэтому у Джава до сих пор нет нормальных дженериков (и не будет), из-за Cвященной Обратной Совместимости!
                  • +2
                    Все, победили, сдаемся. Забавно, но постоянно в таких спорах, при любом удобном случае, стабильно вспоминают про стирание типов:
                    https://habr.com/post/352404/#comment_10733822
                    https://habr.com/post/352404/#comment_10736116
                    В этой теме проскакивает раза три подобное. А забавно тут именно то, что об этой проблеме приходится слышать от людей, которые на Java не пишут. Джаверы же, по моему опыту, не воспринимают это как Страшную Проблему.
                    • 0
                      Я java-разработчик воспринимаю это как еще одну неровность языка из-за которой приходиться таскать с собой постоянно объекта класса. Да проблему можно обойти, но высокоуровневый язык програмирования должен упрощать жизнь, а не вставлять палки в колеса.
                      • 0
                        Никто не говорит, что это хорошо. Да, есть такая проблема. Появилась она не просто так, это был осознанный выбор, который на момент принятия решения, возможно, был лучшим. Речь только про масштаб трагедии.
                        • 0
                          Проблема в общем подходе java когда однажды принятое, возможно хорошее на тот момент решение, не возможно изменить ввиду обратной совместимости.
                      • 0
                        Все, победили, сдаемся. Забавно, но постоянно в таких спорах, при любом удобном случае, стабильно вспоминают про обратную совместимость.
                        В этой теме проскакивает раза три подобное. А забавно тут именно то, что об этой проблеме приходится слышать от людей, которые на .NET не пишут. Дотнетчики же, по моему опыту, не воспринимают это как Страшную Проблему.
                • +1
                  В моём опыте были 2 Java-программы, одна из которых работала только с 1.6.xx, а другая с 1.6.yy (точные xx и yy уже не помню). Вот это было весело.
                  • +2
                    Имел опыт работы с программой которая компилировалась только под java 7, но запускалась только на java 8. Связанно с использованием js движка Rhino корректно работающего только в таком режиме.
                • 0
                  С# не догнать особенно в плане могучего compatibility оного, когда приходится держать на компе net2, net3, net3.5, net4. Представляю сколько крапа придется ставить ещё через 10 лет
                  • +2
                    Вот только Kotlin уже набирает обороты по причине того, что слишком давит совместимость. И может случиться, что будет уже не догнать.
                    • –2
                      Через 10 лет не придется — .NET Standard обратно совместим.
                • +1

                  Ну, "раньше" C# работал только на Винде, а Scala уже 15 лет "набирает популярность".

                  • +1
                    Scala это уже давно (3-4 года) например Spark. И я вот так вот сразу не возьмусь назвать проект на c#, сопоставимый по популярности со спарком. У нее есть свои проблемы, но у нее есть и своя постоянная и немаленькая ниша.
                  • +10
                    Но ведь на КПДВ явно JavaScript…
                  • +2
                    Что касается нового JIT-компилятора, то он направлен на улучшение производительности JVM. Прежняя версия JVM была написана на C++, однако в рамках проекта Metropolis большую часть JVM перепишут на Java.

                    но зачем?
                    • +4

                      Много причин, как минимум:


                      1. Сейчас С2 компилятор очень сложный.
                      2. Для работы этого компилятора необходимо выделять дополнительную unmanaged память, что неудобно при старте (не отвечу про детали, к сожалению).
                      • +2
                        Наверное, чтобы любой Java программист мог форкнуть JVM и допилить что-то свое, например сборку мусора без «остановки мира». В теории это может быть полезно, правда как-то я сомневаюсь, что можно переписать JVM с C++ на Java и при этом увеличить производительность.
                        • 0
                          Затем же наверно что и Roslyn сделали на C#. В разработке JVM такие головы сидели тут в Питере. Говорят перевели всё теперь в Индию.
                      • +6
                        Надеюсь, что в 11-й наконец выкатят asynchronous jdbc.
                        • 0

                          в свете var и строковых литералов, предполагаю что работать оно будет на промисах

                        • –1
                          Чтобы имплементировать такую «простую и необходимую» вещь как честный асинхронный jdbc сначала хотят добавить (снова!) fibers в яву. Что тянет за собой целый ряд неслабых изменений.

                          Называется project Loom: cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html

                          Если поискать в гугле кто ссылается на эту статью — можно найти обсуждения про асинхронный jdbc.
                          • +2
                            Подозреваю, что Loom закончат ещё не скоро. Пока можно и на селекторе сделать.
                        • +5
                          Эти строковые литералы не будут одинаковыми:
                          String html = "<html>\n" +
                                        "  <body>\n" +
                                        "    <p>Hello World.</p>\n" +
                                        "  </body>\n" +
                                        "</html>\n";
                          String html = `<html>
                                           <body>
                                             <p>Hello World.</p>
                                           </body>
                                         </html>
                                        `;

                          Для того, чтобы они стали одинаковыми, предполагаемый литерал из Java 11, будет примерно таким:
                          String html = `<html>
                            <body>
                              <p>Hello World.</p>
                            </body>
                          </html>
                          `;

                          Поправьте, если ошибаюсь
                          • +1
                            JEP 325 (switch expressions)
                            JEP 326 (raw string literals)
                            Они до сих пор на стадии Candidate, не вводите в заблуждение.

                            Вот тут список включенных в релиз JEP и кандидатов для релиза в java 11:
                            openjdk.java.net/projects/jdk/11

                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                            Самое читаемое