Java 10 General Availability


    Ссылка для скачивания

    Последнюю половину года мы подробно обсуждали здесь новшества Java 10 и знаем их наизусть.

    Но было бы странно, если самая главная Java-новость за полгода не появилась бы в этом хабе.


    Как говорится, просто оставлю это здесь. Вперёд к приключениям!


    Действительно вышла в срок?


    Да, действительно. Релиз сделали из 46 билда, и собрали день назад, глядите:


    $ java -version
    openjdk version "10" 2018-03-20
    OpenJDK Runtime Environment 18.3 (build 10+46)
    OpenJDK 64-Bit Server VM 18.3 (build 10+46, mixed mode)

    А в IDE работает, или всё красным перечёркнуто?


    Работает в свежей IntelliJ IDEA. Но придётся поставить бета-версию (например, ideaIU-181.4203.400), потому что на стабильной 2017.3.5 не поддерживается этот language level.




    Долгий путь к релизу


    На самом деле, нет. Это самый быстрый полноценный релиз в истории!


    Раньше план публиковался на странице проекта, но больше он нам не понадобится. Все этапы успешно выполнены.






    И что, всё хорошо?


    В основном, да. В этом релизе разработчики фокусировались на починке только тех багов, которые являются совершенно критичными для успеха Java 10. Все задачи, относящиеся к другим релизам Java, даже с высшим приоритетом, отложены.


    Но какой же релиз без хорошего факапа? Тагир Валеев (lany) через считаные часы опубликовал в своём твиттере новость об эпическом новом баге в компиляторе.



    Баг уже обсуждают в рассылке и ведётся работа по его починке.


    Вот этот код, можно вставить и проверить:


    public class Main {
        void m() {
            var s = java.util.List.of("a", 1);
        }
    }

    Проблема проявляется только только при включённом флаге -g, который говорит о необходимости генерации отладочной информации. В IDE он включён по-умолчанию, так что мимо ошибки не пройти :-)


    Изменения, которые появились в этом релизе



    JEP 286Local-Variable Type Inference.

    Локальный вывод типов с помощью var. Неоднозначная фича. Регулярно вызывает бурления в рассылке.


    Пример кода:


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

    Бородатый анекдот в тему.
    Заходит джавист в столовую и говорит: дайте, пожалуйста, Борщ борщ нью Борщ!





    JEP 296: Консолидация леса исходников JDK в едином репозитории.

    Широкой общественности обычно не интересно, разве что ты собираешь OpenJDK из исходников. Интересней то, что чем меньше хаоса в проекте, тем более качественный получается продукт.





    JEP 304Garbage-Collector Interface.

    Улучшение изоляции основных исходников от GC путём создания хорошего чистого интерфейса для GC. В последнее время стало весьма популярным писать свои GC: на подходе у нас Shenandoah, ZGC, Epsilon. Чтобы поддержать эти благие начинания, разработчикам OpenJDK пришлось конкретно разгрести свалку в коде, чтобы не только максимально упроситить создание новых GC, но и дать возможность быстро отключать ненужные GC из сборки. Один из основных критериев успеха — отсутствие просадки по перфомансу после всех этих рефакторингов.





    JEP 307Parallel Full GC for G1.

    CMS выбросили на мороз, и всё интересное в общеупотребительной (не низкопаузной) сборке мусора теперь происходит в G1. Читаем "Release Note: JEP 307: Parallel Full GC for G1": «Коллектор G1 создан для того, чтобы обходиться без full GC, но когда параллельная сборка не может утилизировать память достаточно быстро, происходит возвращение к full GC. Старая реализация full GC в G1 использовала однопоточный алгоритм mark-sweep-compact. После реализации JEP-307, full GC параллелизовался и стал использовать то же количество параллельных тредов-воркеров, как в young и mixed». (Напоминаю, что young GC обрабатывает только регионы young/survivor, mixed — ещё и old, full — весь хип, young/tenured).





    JEP 310: Application Class-Data Sharing.

    Чтобы ускорить запуск и уменьшить количество используемой памяти, предлагается расширить существующую фичу под названием Class-Data Sharing («CDS») возможностью упаковки классов в общий архив.


    Если совсем коротко, то вот так архив вначале создаётся, а потом используется при запуске:


    java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=hello.lst -XX:SharedArchiveFile=hello.jsa -cp hello.jar
    
    java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa -cp hello.jar HelloWorld




    JEP 312Thread-Local Handshakes.

    Возможность выполнять колбэк на тредах, не делая глобальный для JVM сейфпоинт. Фича позволяет дешёво останавливать одиночные треды, а не только «всё или ничего». Это низкоуровневая системная фича, вручную ей воспользоваться нельзя, но можно радоваться автомагически возросшей производительности программ.





    JEP 313: Remove the Native-Header Generation Tool.

    Утилита javah больше не нужна, потому что нативные заголовки теперь может делать javac (начиная с JDK8, на самом деле).


    javah была утилитой, генерирующей сишные заголовочные файлы и исходники, необходимые для использования нативных методов. Сгенерированные ей файлы предназначены для использования в программах, написанных на Си, чтобы обращаться к экземплярам джавовых объектов из неуправляемого нативного кода. В .h-файле определяется структура, которая выглядит примерно как класс, которым мы собираемся управлять. Поля структуры — переменные экземпляра класса. Тем не мнее, в JNI использование подобных стабов не является обязательным.





    JEP 314Additional Unicode Language-Tag Extensions.

    Поддержка новых расширений Unicode: cu (currency type), fw (first day of week), rg (region override), tz (time zone).





    JEP 316Heap Allocation on Alternative Memory Devices.

    HotSpot VM теперь может выделять хиповую память на других девайсах, например, на NV-DIMM. Некоторые операционки уже умеют выделять не-DRAM память, помещая её на файловую систему, например, NTFS DAX и ext4 DAX. Добавляется опция ` -XX:AllocateHeapAt=.




    JEP 317Experimental Java-Based JIT Compiler.

    Graal, можно использовать как основной JIT-компилятор. Объяснять, что такое Graal — очень долго, поэтому вкратце. Под брендом Graal сейчас объединено несколько направлений: Graal Compiler, SubstrateVM, Truffle, различные языки для него ("Graal polyglot runtime"). В данном случае имеется в виду именно Compiler. На некоторых тестах, типа Scala DaCapo, грааль позволяет получить почти двухкратную производительность по сравнению с C2! Чтобы получить подобные чудесные результаты, необходимо иметь очень-очень много динамического кода и очевидно, наибольшую пользу тут извлекут программисты на Scala, Groovy, JavaScript, и т.п. Работает это чудо пока что только на 64-битных Linux и macOS.





    JEP 319Root Certificates.

    В JDK имеется кейстор cacerts, который нужен для хранения корневых сертификатов. Но в OpenJDK он пока пустой. Поэтому ништяки типа TLS в OpenJDK по-умолчанию не работают. Теперь этот cacerts будет правильно сконфигурирован и заполнен, и ништяки начнут работать. Кроме того, это сгладит разницу между OpenJDK и Oracle JDK.





    JEP 322Time-Based Release Versioning.

    Feature releases будут добавлять новые фичи. Update releases будут только чинить баги.


    Ну и конечно же,


    $ java -version
    openjdk version "10" 2018-03-20
    OpenJDK Runtime Environment 18.3 (build 10+46)
    OpenJDK 64-Bit Server VM 18.3 (build 10+46, mixed mode)
    



    Не всё есть в JEP


    В багтрекере и рассылке можно увидеть большое количество изменений, которые не получили такую широкую огласку, как основные JEP.


    По этому поводу Тагир Валеев (lany) недавно написал очень хорошую статью. Дублировать её содержимое нет смысла, нужно пройти по ссылке и прочитать.


    Что дальше?


    Необходимо взять JDK 10 и начать миграцию на него своего кода!


    Ссылка на загрузку.


    Минутка рекламы. Как вы, наверное, знаете, мы делаем конференции. Ближайшая конференция по Java — JPoint 2018. Она пройдет 6-7 апреля 2018 года в Москве. В докладах часто упоминаются вопросы перехода на новые версии Java. Какие доклады там бывают — можно посмотреть в нашем архиве на YouTube или прочитать в хаброблоге. Кроме того, можно будет вживую пообщаться с докладчиками и лучшими экспертами по Java-платформе в специальных дискуссионных зонах после каждого доклада. Короче, заходите, мы вас ждём.

    JUG.ru Group

    1 382,38

    Конференции для взрослых. Java, .NET, JS и др. 18+

    Поделиться публикацией

    Похожие публикации

    Комментарии 84
      +2
      потому что на стабильной 2017.3.5 не поддерживается этот language level.

      Если я правильно помню, там был более хитрый алгоритм: надо просто написать var x = "foo", а когда подсветит красным, там есть квик-фикс на нём. Так-то в 2017.3 у нас уже всё работало. Но вообще да, проще на 2018.1 уже перейти.

        +1
          +1
          А можно вашу цветовую схему узнать?
            0

            Это очень крутой плагин под названием Material Theme UI (точнее, Material Theme UI EAP по понятной причине). Оно меняет все картинки и цвета в UI. Это одна из стандартных схем, идущих с ним в коробке: Material Palenight. Там ещё несколько клёвых схем в комплекте есть!


            Очень рекомендую. Я бы на месте JB вообще поставил бы этот плагин по умолчанию, уж слишком всё няшное стаёт.

              +1
              Material Theme UI

              Этот кстати сейчас обновляется гораздо активнее, а EAP разработчик кажется забросил полгода назад.
                0

                Ох ничоси. Обновлюсь-ка на него.

                +1
                Что-то он на смену размера шрифта не реагирует…
                  0
                  А где меняешь? Editor -> Color Scheme -> поставить галку «Use color scheme font instead of default», выставить значение Size
                    +1
                    Да, уже нашел, спасибо!

                    пока непривычно как-то :) Но няфффно, это да :D
          +8
          >> Необходимо взять JDK 10 и начать миграцию на него своего кода!
          … Эпический баг компилятора
          Вы точно уверены? ))
            +10
            Ну дык а как еще найти все мешающие нормальным людям баги?
            +15

            Заходит джавист в столовую и говорит: дайте, пожалуйста, вар борщ нью Борщ!

              +11
              Заходит Спрингист в столовую:
              — Суп!
              — Борщ, Гороховый, Солянку?
              — NoUniqueBeanDefinitionException…
                +5
                повезет ему, если будет суп дня (с аннотацией Primary)
                +1
                удалил.
                  +3

                  А я рад, что наконец-то будет var вместо LinkedHashMap <String, HashMap <String, Object>> и подобного.
                  Наличие вар не запрещает указывать типы там, где это нужно...


                  Многословие джавы отталкивает людей, есть что улучшать, никого не обидев, сохраняя баланс

                    +4
                    На code-review, когда используется такой вывод типов, постоянно возникает вопрос, а подумал ли автор о типе переменной, он (тип) действительно не важен или человеку было просто лень и он «фигачил» строки одна за одной? Не знаю как в Java, а в C++ это довольно важный аспект при написании кода.

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

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

                    Многие ещё говорят, что IDE же выводит тип, только вот у вас когда определенно 10 переменных и у всех auto, это все равно мука узнавать и запоминать, какой тип где, а через какое-то время повторять эту процедуру.

                    Жаль, что строгость кода почему-то не находит понимание.
                      +1
                      почему тип неважен?
                      скорее следует понимать, что var делает такой же тип как с права.
                      что и нужно в 99% процентах случаев создания объекта, где это и напрягает тавтологией.
                        +2
                        почему тип неважен?

                        В случае, когда auto x = new Something, да, тавтология уходит, тут имелся в виду случай auto users = smth.getUsers()
                          +1
                          А дальше например идет foreach по этому контейнеры (то что это контейнер ясно из название функции и переменной, однако тут же вопрос, а вдруг там не линейный контейнер, а какой-то более сложный тип?)
                            +1
                            однако тут же вопрос, а вдруг там не линейный контейнер, а какой-то более сложный тип?

                            Названия функции-фабрики и принимающей переменной не подразумевают никакой специфики.
                              0
                              В местах где невсё так очевидно, никто не запрящает писать тип(хотя это и затрудняет порой рефакторинг)
                              а тавтология резко снижает читабельность
                              имя типа контейнера запросто может выйти 50+ символов — повторять както нечитабельно.
                          0
                          Я обычно пишу выражение, потом нажимаю ctrl+alt+V в Идее, запускается рефакторинг Extract Variable, и остаётся только вписать название новой переменной. То есть по сути, происходит то же самое что и с var, но убого.
                            +1
                            В Idea можно еще .var после выражения написать.
                            +1
                            10 переменных и у всех auto, это все равно мука узнавать и запоминать, какой тип где

                            auto и var — все-таки разные вещи, хотя и юзкейсы похожи. Характерно то, что у Майерса про вывод типов отдельная глава в книжке, а про var редко где больше одного абзаца пишут.

                            Но что значит «запоминать тип»? Он неоднозначен или контекст теряется настолько, что даже имя не может помочь определиться?

                            Жаль, что строгость кода почему-то не находит понимание.

                            Строгости кода это не мешает, зато DRY поддерживает.
                              0
                              Зачем типы запоминать, есть же IDE. Можно или навести мышкой с зажатым ctrl, или если не используешь мышку — нажать ctrl+Q когда переменная под курсором
                                +5
                                Мышкой водить по всем переменным — тоже не самое продуктивное решение и не факт, что с тем же auto подсказка будет полезной. Да и всякие диффы смотреть в разных приложениях, которые не умеют анализировать типы в контексте проекта, будет не так удобно.

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

                                  Я постараюсь дизайнить API так, чтобы было совершенно всё равно, какие там типы. В частности, названия типов не должно быть частью имени метода.


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

                                    +1
                                    Я постараюсь дизайнить API так, чтобы было совершенно всё равно, какие там типы.
                                    Я бы посмотрел на такой API, где в названиях намеренно избегают любых отсылок к типам) Шутка, я бы не хотел такого видеть никогда.
                                    Если серьезно, тут уже был примерчик насчет метода getUsers(). Вам что-либо говорит это название о том, что из него можно получить?
                                      +2

                                      Что угодно оно может вернуть. List, Set, Array, и даже Queue!


                                      Дальше результат, скорей всего, будет итерироваться через короткую форму записи for loop. При этом знать, какой там конкретный формат хранения — не нужно, for сработает со всеми!


                                      Тут можно бы спросить: а что, если getUsers() вернёт HashMap? Фокус не сработает?


                                      Конечно сработает, потому что IDE-то знает о настоящем типе!


                                      Как происходит итерирование в IntelliJ IDEA? Ты пишешь слово iter и нажимаешь [TAB]. Вылезает вот такая подсказка:




                                      Которая после применения ведёт, например, к такой замене:




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




                                      Работает ли это с var? Да, работает.




                                      Работает ли это с var, который получает данные снаружи? Работает.




                                      Такие дела.


                                      Не нужно вводить сущности, которые не нужны. Не сломается то, чего нет.


                                      В данном случае нам не нужно знать способ хранения юзеров.

                                        0
                                        Что угодно оно может вернуть. List, Set, Array, и даже Queue!
                                        Именно! Здесь будет некая Collection<User>. Не указав тип явным образом мы создали у программиста-юзера необходимую ассоциацию в терминах предметной области.
                                        Тут можно бы спросить: а что, если getUsers() вернёт HashMap? Фокус не сработает?
                                        Конечно нет. А какого вида хэшмап от юзеров вы себе представляете? Словарь, как правило, отражает какое-то отношение (ключ-значение, которые вряд ли будут относиться к единой сущности), а никак не множества (в математическом смысле) значений. Тогда и названия будут иными.
                                      +1
                                      когда у тебя какой-нибудь чудовищный тип, например, лист мапов мапов мапов из листов в листы. И ты этот тип не хочешь видеть глазами, потому что он напрягает.

                                      Вот я такой тип не столько видеть не хочу, сколько работать с ним. Потому что видеть я его может и перестану, а думать о нем придется — где в этой каше что, и как именно извлекается. По-моему такого психоза лучше избегать всеми силами, и var тут только маскирует проблему, а не решает ее.
                                    +1
                                    Вывод типа то есть, но это в любом случае надо позиционировать курсор на переменной и нажимать клавиши. Если таких переменных много, то вызывает больше неудобств, чем сложностей у человека указать явно тип, когда он писал код.
                                    +2
                                    auto и var — все-таки разные вещи, хотя и юзкейсы похожи.

                                    Прошу меня извинить за непонимаю, что там придумали в Java, но кажется auto просто более фунциональней, потому что можно писать, например auto * или const auto &. А так же ещё auto можно засовывать в тип аргумента функции (шаблоны для бендых) и результирующее значение. Или же я изначально не прав?

                                    Но что значит «запоминать тип»? Он неоднозначен или контекст теряется настолько, что даже имя не может помочь определиться?

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

                                    Строгости кода это не мешает, зато DRY поддерживает.

                                    Вам тоже отмечу, что против конструкции auto x = new Something ничего против не имею. Проблема возникает, когда зовут функцию, например process, в которой название отвечает за действие, а не за тип возвращаемого значения.
                                    auto r = process();
                                    Что такое r? Какой-то результат. Не везде есть возможность и тип результата и действие уместить в одно название и неПолучитьОченьДлинноеНазваниеФункцииКотораяДелаетААвозващаетБ
                                      +1
                                      auto просто более фунциональней

                                      В том и дело, результат auto не так очевиден, как с var, поэтому в C++-сообществе и бурлят споры насчет его использования в местах, где это не необходимо (локальные переменные, которые не про шаблоны). Так что, наверное, правота здесь относительна (=

                                      Запомнить в прямом смысле)

                                      Но вам же все равно придется запоминать что-то большее про тип, чем его имя, вне зависимости от использования auto, верно? А тут еще правила вывода, специфичные для auto. Потому мозг и кипит, я вас понимаю. Вывод типа тоже нужно применять с умом, ведь писать var там, где достаточно int — это оверкилл.

                                      например process, в которой название отвечает за действие

                                      Что это за результат по имени «r»? Может это errorCode или report? Согласитесь, auto report = ... лучше, чем Report r = ..., а auto errorCode=... лучше, чем int r=..., ведь потом наверняка идет что-то вроде:
                                      return report.isSuccess();
                                      // или
                                      if ( errorCode == PROC_SUCCESS )

                                      и однобуквенное название заставляет идти туда, где оно инициализировано. Да, возможно это чем-то похоже на венгерскую нотацию, но оно более семантично, т.к. привязывается не к типу имплементации, а к значению в контексте конкретного юзкейса.
                                        +2
                                        Что это за результат по имени «r»?

                                        Пардон, кусок кода был для обозначения конструкции. Однобуквенное название было лишь показатель того, что тут какой-то идентификатор.

                                        auto errorCode=… лучше, чем int r=...

                                        Все же, если там не int, а какой-то внятный enum (аля enum class в C++), то на мой взгляд ErrorCodeType error = process() лучше, чем auto errorCode = process(). Но тут уже кажется больше вкусовщина.

                                        Не очень хочу спорить, потому что, к сожалению, имею только два осмысленных аргумента
                                        1. усложняет чтение кода (скажем так, микроусложнение, но разве кто-то возразит, что его нет?).
                                        2. со временем отупляет и уже перестаешь задумываться, а что там за тип под капотом, что иногда приводит к очень глупым ошибкам, которые можно бы было избежать подумав, правильный ли тип у переменной: самая простая ошибка — не влезло значение, потому что auto/var вывело int32, а мы потом умножили его несколько раз или вычли из unsigned и ушли за ноль.

                                        Есть ещё третий момент, но он относится лишь к несовершенности IDE которыми довелось пользоваться. «Find usages» порой находит не всё (по разным причинам), а если везде указан тип, то достаточно бы было сделать grep по всем исходникам.
                                          +1
                                          усложняет чтение кода
                                          Все зависит от кейса. Вы же согласились насчет Борщ борщ = new Борщ();? Так вот и я категорически против распихивания вывода типов везде, где скомпилируется.

                                          со временем отупляет
                                          И волосы на руках начинают расти!) Про автокомплит когда-то то же самое говорили.

                                          auto/var вывело int32, а мы потом умножили его несколько раз или вычли из unsigned и ушли за ноль
                                          Вы пишите выражение с каким-то параметром, если не подумали про переполнение типа, то явное его декларирование не спасет.

                                          а если везде указан тип, то достаточно бы было сделать grep по всем исходникам.
                                          Аргумент, вместо прямого поиска вам придется найти фабрику и грепать по ней. Хотя, это настолько же усложняет рефакторинг типа возврата.
                                            +1
                                            со временем отупляет

                                            тогда функциональное программирование — это вообще ад и содомия, мозгов не остаётся совсем!

                                    0
                                    Вот ей-бо, лично мое мнение — если в коде появляется LinkedHashMap <String, HashMap <String, Object>>, то это уже проблема, и var ее не решает, а маскирует.
                                      0
                                      Что касается абстрактных структур вы правы, но в UI часто встречаются конструкции типа controller, который параметризован специфическим view, который, в свою очередь, параметризован типизированным Editor и Table :) И это не предел. Да — имя каждого из этих классов складывается из 3-4 далеко не коротких слов.
                                        0
                                        Для таких случаев придумали классы-обертки, фасады и прочие умные слова. Неужели прям никак не получится спрятать под капот весь такой психоз?
                                  +4
                                  Не-а, не будем мы мигрировать. Мы по старой энтерпрайзной привычке подождём LTS. Тем более, что до него недолго совсем осталось.
                                    +4
                                    Блин, что делается, куда мир летит, мы еще на 8 джаву не перешли толком (а кое-где еще и с 6 не слезли, и даже 7 еще кажется какой-то опасной новой диковиной на которую никак перекатить кучи легаси проектов не могут), а тут уже 10 выходит. Куда вообще 9 делась, я ее даже заметить не успел! Ааа, остановитесь, подождите, я не успеваю.
                                      +3

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

                                        0
                                        «горшочек, не вари!»
                                        +3
                                        Ну и как обычно, для многих библиотек выход новой Java — полная неожиданность.
                                        К примеру, Lombok не работает.
                                          +3
                                          Так нечего было им пользоваться :-) Понятно, что такие шибко хакерские вещи, которые прямо скажем ломают джаву изнутри, сами очень хрупкие.
                                            0
                                            А почему они его не проапдейтили до десятки?
                                              +2

                                              На самом деле проапдейтили, даже в CHANGELOG написали, только поленились выпустить свежую версию почему-то. А вообще ты донат занёс людям или только требовать умеешь? ;-)

                                                +1

                                                Хотя, конечно, вру. "Some initial work on supporting JDK10" звучит совсем неубедительно.

                                                  0
                                                  Очень забавно было бы посмотреть на диффы того, что такое это «some initial work». Может быть в них есть какие-то интересные тайные аспекты интеграции с JDK.
                                                    +2
                                                    Парсинг версии пофиксали.
                                                      +3
                                                      Коммит так коммит! Можно теперь полгода отдыхать!
                                                  0
                                                  > А вообще ты донат занёс людям или только требовать умеешь? ;-)

                                                  Я умею не использовать у себя Lombok! :-)

                                                  Alt+Enter, Getter and Setter, Enter, Enter, как-то так. А ещё можно расчехлить JavaParser и переехать им исходники в цикле, если совсем ленивый.
                                                    +2
                                                    Блин, а я публичные поля оставляю просто.
                                                      +3
                                                      А я делаю геттеры-сеттеры, потому что в течение N лет старшие товарищи били по рукам, когда пытался делать публичные поля.

                                                      Почему это нужно всегда делать, я так и не понял. Но карго-культу продолжаю следовать…
                                                        +1
                                                        Почему это нужно всегда делать, я так и не понял. Но карго-культу продолжаю следовать…

                                                        Не вы один… /смотрит с укором на половину своего кода, построенного по принципу карго-культа, вздыхает с мыслью «ну зато работает збс»...
                                                          +1

                                                          Объекты надо любить! Раз в год бывает нужда таки расширить геттер или сеттер и вставить проверку, например.


                                                          Насколько это оправдывает геттеры/сеттеры — хз.

                                                            0
                                                            У меня в вебе все проверки в отдельных классах-валидаторах)
                                                              +1

                                                              Это же не тру ООП!


                                                              Ну ещё ломбок генерит конструкторы, и это круто работает с новым Спрингом — можно писать private final поля, Ломбок сгенерит конструктор и спринг через конструктор вставит бины.

                                                                +1
                                                                Это же не тру ООП!

                                                                Почему? Наоборот, SOLID во все поля! Под задачу валидации выделен отдельный класс, который несет только одну ответственность :D
                                                                  0
                                                                  тут yegor256 может рассказать, как правильно
                                                                    +2
                                                                    Спасибо. Не надо!
                                                                      0

                                                                      Надо, Федя, надо :-)

                                                                  +2

                                                                  И валидацию параметров конструктора ломбок прикрутит? Если у меня class Range { private final int from, to; } и инвариант from <= to, куда мне инвариант впихнуть?

                                                                    +1

                                                                    В этом случае мы пишем конструктор.
                                                                    Ломбок — молоток, шурупы им не закручиваем.


                                                                    Если в проекте гвоздей нет — то Ломбок и не нужен. Нам лично, в нашем проекте — он помогает.

                                                                  +1

                                                                  У меня в коде иногда бывает сначала:


                                                                  public long getTotal() {
                                                                       return this.number1 + this.number2;
                                                                  }

                                                                  А потом выясняется что нужно хранить в базе и тогда получается:


                                                                  public long getTotal() {
                                                                       return this.total;
                                                                  }

                                                                  Геттеры/Сеттеры все таки полезны. Тем более они генерируются IDE по одной кнопке.

                                                                    +1
                                                                    Сделать правильный геттер или сеттер в случае с ломбоком не сложно. Достаточно его просто написать.
                                                                    А в связанном коде оно и так все через геттеры и сеттеры работает.
                                                              +1
                                                              Можно я буду ссылаться на этот коммент, когда мне в следующий раз скажут, что публичные поля — это не по феншую?
                                                                +1
                                                                Можно! Главное — головой думать, когда программируешь, а не фэншуем заниматься.
                                                                +1
                                                                в JPA… приходится гетеры, и даже конструкторы писать.
                                                                +1

                                                                Мы начали его использовать, когда поля постоянно менялись, была такая дикая фаза. Сейчас поспокойней, но Lombok как-то прижился.

                                                            +1

                                                            Да ладно. И ещё кучей вещей не пользоваться. Сидеть на голой джаве.


                                                            Есть подозрение, что сломан не только Lombok. Просто он самый первый в цепочке компиляция-запуск. И дальше я пока не прошел, проще подождать немного, пока пофиксят.


                                                            В прошлый раз, уже после выхода 9, были проблемы у jooq. Logstash вроде бы до сих пор на 9 не запускается.


                                                            Блин, похоже, удел ынтырпрайза — LTS :(

                                                              0
                                                              То есть LTS — это удел ынтерпрайза, а вот юзать сырую, никем кроме трех человек не поддерижваемую штуку Lombok — это конечно ого-го удел :)
                                                                +1

                                                                Так я же 10 для себя попробовал :)
                                                                На личном проекте, где 9 работает.
                                                                Но там Ломбок больше по привычке.


                                                                На работе — 8, там Ломбок работает отлично.

                                                          +2
                                                          Утилита javah больше не нужна, потому что нативные заголовки теперь может делать javac

                                                          Очень интересно. Я правильно понимаю, что если у меня сорцы на котлине, то теперь хрен мне, а не jni? Спасибо тебе, Оракл, что заставляешь в полностью котлиновском проекте заводить единственный джавовый класс со всеми нативными методами.
                                                            +1
                                                            Разве Котин генерит что-то специфичное для десятой жабы? А как придёт время, в JB что-нибудь придумают, наверняка у них самих external'ов дофига

                                                            Можно попробовать выделить external методы в отдельные классы, собирать их с jvmTarget=1.8, и потом натравливать на них javac из старых версий JDK
                                                              +2
                                                              Так javac же принимает на вход сорцы! И именно поэтому я не могу натравить его на котлин. В отличии от javah, которому нужны .class.
                                                                +1
                                                                Юзай javah из старых версий JDK, его же никто не забрал :)

                                                                Ещё тут не хватает belovrv и elizarov
                                                                  +2

                                                                  javah из старых версий не съест скомпилированный в новую версию класс. Впрочем, Котлин пока новее восьмёрки версии не выдаёт. Таргетить на 9-10 Котлину, наверно, смысла и нет. А вот если в 11 нестмейты выкатят, Котлин от этого выиграет.

                                                              0

                                                              а чойта я отвечаю, тут же специальные люди © для этого есть: sudo cast --verbose abreslav

                                                                0
                                                                подозреваю, что в котлиновский компилятор впилят генерилку
                                                                0
                                                                Java программисты, вот скажите честно, Борщ борщ нью Борщ это смешно?
                                                                  0
                                                                  Да. А АбстрактнаяКухняКонкретныхКухоньБорщей еще смешнее, потому что шутка ынтырпрайз эдишн!

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

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