Pull to refresh

Comments 84

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

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

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

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


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

Material Theme UI

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

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

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

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

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

Заходит Спрингист в столовую:
— Суп!
— Борщ, Гороховый, Солянку?
— NoUniqueBeanDefinitionException…
повезет ему, если будет суп дня (с аннотацией Primary)
UFO just landed and posted this here
На code-review, когда используется такой вывод типов, постоянно возникает вопрос, а подумал ли автор о типе переменной, он (тип) действительно не важен или человеку было просто лень и он «фигачил» строки одна за одной? Не знаю как в Java, а в C++ это довольно важный аспект при написании кода.

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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


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


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


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


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




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




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




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




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




Такие дела.


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


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

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

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

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

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

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

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

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

и однобуквенное название заставляет идти туда, где оно инициализировано. Да, возможно это чем-то похоже на венгерскую нотацию, но оно более семантично, т.к. привязывается не к типу имплементации, а к значению в контексте конкретного юзкейса.
Что это за результат по имени «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 по всем исходникам.
усложняет чтение кода
Все зависит от кейса. Вы же согласились насчет Борщ борщ = new Борщ();? Так вот и я категорически против распихивания вывода типов везде, где скомпилируется.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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


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

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

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

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

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


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

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

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

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


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


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


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

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

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


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

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

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

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

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

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

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

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