Какие существуют необычные приёмы в Java?
От: cppguard  
Дата: 09.01.22 08:21
Оценка:
В С++, например, придумали Type lists или CRTP, и вообще много всяких трюков, но в Java самое необычное, что я знаю, это двойная диспечеризация. А какие приёмы вы знаете?
Re: Какие существуют необычные приёмы в Java?
От: scf  
Дата: 09.01.22 08:34
Оценка:
Здравствуйте, cppguard, Вы писали:

C>В С++, например, придумали Type lists или CRTP, и вообще много всяких трюков, но в Java самое необычное, что я знаю, это двойная диспечеризация. А какие приёмы вы знаете?


аннотации, кодогенерация в рантайме, OSGI, offheap...
Re: Какие существуют необычные приёмы в Java?
От: halo Украина  
Дата: 09.01.22 17:47
Оценка:
Здравствуйте, cppguard, Вы писали:

C>... но в Java самое необычное, что я знаю, это двойная диспечеризация.


Так в Java, как в языке, её-то и нет. На уровне байткода JVM, если не ошибаюсь, тоже нет. Множественная диспетчеризация реализуется вручную с помощью instanceof и последующих приведений к типу, или с помощью шаблона Посетитель (если на "уровень выше"). В Groovy и Clojure, JVM-языках, вроде как, есть на уровне языков. Но чего-то необычного в ней не вижу совсем.
Re[2]: Какие существуют необычные приёмы в Java?
От: cppguard  
Дата: 09.01.22 22:51
Оценка:
Здравствуйте, halo, Вы писали:

H>Но чего-то необычного в ней не вижу совсем.


Так расскажите про необычное
Re: Какие существуют необычные приёмы в Java?
От: C0s Россия  
Дата: 10.01.22 02:29
Оценка:
Здравствуйте, cppguard, Вы писали:

C>А какие приёмы вы знаете?


Из относительно обыденного, но несколько необычного для неофита могу выделить "умные" enum'ы, которые строятся за счёт имплементации нужных интерфейсов форвардингом их реализациям в нетривиальных закулисных классах.
Re: Какие существуют необычные приёмы в Java?
От: vsb Казахстан  
Дата: 10.01.22 02:52
Оценка: +1
На мой взгляд всё самое необычное в JVM. И в основном связано с кодогенерацией и Unsafe. Как язык Java намеренно сделан таким, чтобы там не было никаких необычных приёмов, я сходу даже ничего и не вспомнил.
Re[2]: Какие существуют необычные приёмы в Java?
От: cppguard  
Дата: 10.01.22 05:49
Оценка:
Здравствуйте, C0s, Вы писали:

C0s>Из относительно обыденного, но несколько необычного для неофита могу выделить "умные" enum'ы, которые строятся за счёт имплементации нужных интерфейсов форвардингом их реализациям в нетривиальных закулисных классах.


Где можно об этом почитать?
Re[3]: Какие существуют необычные приёмы в Java?
От: halo Украина  
Дата: 10.01.22 06:02
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Здравствуйте, halo, Вы писали:


H>>Но чего-то необычного в ней не вижу совсем.


C>Так расскажите про необычное


Да их-то, в принципе, и нет. Генерация кода и AST на лету как в Lombok? Вряд ли. Возможность создать объект, не вызвав конструктор класса? Вряд ли. "Чёрная магия" с CGLIB для проксирования, но зато с кучей ограничений? Вряд ли. Критерии "необычности"-то какие?
Re: Какие существуют необычные приёмы в Java?
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.01.22 21:05
Оценка:
Здравствуйте, cppguard, Вы писали:

C>В С++, например, придумали Type lists или CRTP, и вообще много всяких трюков, но в Java самое необычное, что я знаю, это двойная диспечеризация. А какие приёмы вы знаете?


Ну, можно, например, написать на Java интерпретатор LISP, а на LISP'е содержательную часть программы. Будет выглядеть весьма необычно, и заменить того, кто это сделал, другим сотрудником, работодателю будет несколько проблематично.
Re[2]: Какие существуют необычные приёмы в Java?
От: vsb Казахстан  
Дата: 10.01.22 21:06
Оценка: :)
Здравствуйте, Pzz, Вы писали:

C>>В С++, например, придумали Type lists или CRTP, и вообще много всяких трюков, но в Java самое необычное, что я знаю, это двойная диспечеризация. А какие приёмы вы знаете?


Pzz>Ну, можно, например, написать на Java интерпретатор LISP, а на LISP'е содержательную часть программы. Будет выглядеть весьма необычно, и заменить того, кто это сделал, другим сотрудником, работодателю будет несколько проблематично.


Это ты про Clojure сейчас написал?
Re: Какие существуют необычные приёмы в Java?
От: Artem Korneev США https://www.linkedin.com/in/artemkorneev/
Дата: 21.01.22 23:17
Оценка: 4 (1)
Здравствуйте, cppguard, Вы писали:

C> А какие приёмы вы знаете?


Из того, что я сам делал, на ум приходит:

— Убрать NULL'ы, запретить присваивать NULL ссылкам на этапе компиляции, если не указана аннотация @Nullable. А @Nullable будет требовать в явном виде проверить на Null перед разыменованием ссылки. Позволяет забыть уже наконец, что такое NullPointerException.

— Обернуть объекты своей предметной области в Kotlin и получить рабочий DSL к своему проекту (Domain Specific Language). Удобно для юнит тестов. В продакшн коде я пока не пробовал.

— Dependency Injection. Очень удобная вещь сама по себе.

— Dependency Injection + Aspect Oriented Programming. Кажется, оно так называется. Внедряем Dependency Injection и принудительно добавляем свои классы-обёртки вокруг зависимостей. Получаем прозрачное логирование, прозрачные метрики и т.п., убираем логирование исключений из основного кода за ненадобностью.
С уважением, Artem Korneev.
Re[2]: Какие существуют необычные приёмы в Java?
От: cppguard  
Дата: 21.01.22 23:57
Оценка:
Здравствуйте, Artem Korneev, Вы писали:

AK>- Убрать NULL'ы, запретить присваивать NULL ссылкам на этапе компиляции, если не указана аннотация @Nullable. А @Nullable будет требовать в явном виде проверить на Null перед разыменованием ссылки. Позволяет забыть уже наконец, что такое NullPointerException.


Это делается на уровне IDE?

AK>- Обернуть объекты своей предметной области в Kotlin и получить рабочий DSL к своему проекту (Domain Specific Language). Удобно для юнит тестов. В продакшн коде я пока не пробовал.


Обернуть, в смысле сделать мост для RPC? Я думал, что для Java <-> Kotlin interop ничего не нужно делать, потому что и то, и другое компилируется в байт-код. А чем Kotlin лучше JS или Python? Я использую JS как DSL через Nashorn, и за исключением проблем с поддержкой ECMA6 пока недостатков не выявил. Задумывался о Python или Ruby, но неохота пока тащить дополнительные зависимости.

AK>- Dependency Injection + Aspect Oriented Programming. Кажется, оно так называется. Внедряем Dependency Injection и принудительно добавляем свои классы-обёртки вокруг зависимостей. Получаем прозрачное логирование, прозрачные метрики и т.п., убираем логирование исключений из основного кода за ненадобностью.


Речь про AspectJ или что-то другое?
Re[3]: Какие существуют необычные приёмы в Java?
От: Artem Korneev США https://www.linkedin.com/in/artemkorneev/
Дата: 22.01.22 22:38
Оценка: 5 (2)
Здравствуйте, cppguard, Вы писали:

AK>>- Убрать NULL'ы, запретить присваивать NULL ссылкам на этапе компиляции, если не указана аннотация @Nullable. А @Nullable будет требовать в явном виде проверить на Null перед разыменованием ссылки. Позволяет забыть уже наконец, что такое NullPointerException.

C>Это делается на уровне IDE?

На уровне IDE (Intellij IDEA) и на этапе компиляции, через статический анализатор ErrorProne с плагином NullAway от Uber. У меня оно работало и с Maven и с Bazel. Думаю, что и для других систем сборки можно всё настроить.
В принципе, этой связки уже достаточно для того чтоб убрать проблему с Null'ами, но по умолчанию оно рассматривает любые ссылки как Nullable, а мне это было не очень удобно. Я скопипастил откуда-то примитивную аннотацию, которая рекурсивно делает все ссылки @NotNull по умолчанию и эту аннотацию можно добавить на весь package, получается намного удобнее.

Из всего этого подхода логически следуют лишние проверки после вызовов сторонних пакетов — мы-то может быть и знаем, что какой-то вызов никогда не вернёт Null, но аннотации нет, так что компилятор будет требовать проверку. Для часто используемых API можно создать свои описания, где указать, какие вызовы не нужно проверять на Null.

AK>>- Обернуть объекты своей предметной области в Kotlin и получить рабочий DSL к своему проекту (Domain Specific Language). Удобно для юнит тестов. В продакшн коде я пока не пробовал.

C>Обернуть, в смысле сделать мост для RPC?

Не, всё проще. Да, код Java можно вызывать из Kotlin напрямую, но если ограничиться просто вызовом кода, то большой разницы в выразительности кода нет, особенно со свежими версиями Java. Но мы можем обернуть нужные нам объекты в новые функции на Kotlin с тем чтоб получить такой синтаксис:



Это реальный исполняемый код юнит-теста. Слова типа "failover" это сценарии юниттеста, это исполняемая функция, которая ожидает параметр initialState и после выполнения нужных действий она вызывает функцию afterFailover, в которую передаёт параметр reassigned. Ну а ассерт уже проверяет, что полученная после failover (отказ основной ноды) конфигурация совпадает с конфигурацией второй ноды. Т.е. аварийное переключение отработало как надо.

Вот, для сравнения, полностью аналогичный код юнит теста на Java:



Пример не полный, там в классе с юнит тестом есть объекты haService и facade, но думаю что сама идея и без них понятна.

C>А чем Kotlin лучше JS или Python?


Kotlin это язык для всё той же JVM, его очень легко использовать с Java. Плюс, это язык со статической типизацией, так что мы имеем все те же проверки времени компиляции, что с для Java.
Ну а вообще — дело вкуса, наверное.

C>Я использую JS как DSL через Nashorn




AK>>- Dependency Injection + Aspect Oriented Programming. Кажется, оно так называется. Внедряем Dependency Injection и принудительно добавляем свои классы-обёртки вокруг зависимостей. Получаем прозрачное логирование, прозрачные метрики и т.п., убираем логирование исключений из основного кода за ненадобностью.

C>Речь про AspectJ или что-то другое?

Не, всё проще. Я не уверен, что AOP тут подходящий термин, может быть я его неправильно воткнул.
То, что я имел в виду — что при использовании dependency injection мы имеем более гибкий контроль над созданием зависимости. Например, если нам нужно вернуть реализацию интерфейса Engine, то мы можем вернуть этот самый Engine, прозрачно обёрнутый в Logger, PermissionsChecker, MetricsUpdater и т.п., получится что мы применим все эти фичи ко всем нужным нам подсистемам, при этом нам не нужно менять код тех подсистем. Это называется Interceptor, если по моим словам не понятно, что я имею в виду, я могу порыться в исходниках, поискать наглядные примеры.
С уважением, Artem Korneev.
Re[2]: Какие существуют необычные приёмы в Java?
От: Worminator X Россия #StandWithPalestine 🖤🤍💚
Дата: 06.05.22 13:00
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Ну, можно, например, написать на Java интерпретатор LISP, а на LISP'е содержательную часть программы.


Делал такое, когда писал компилятор на Java. Самодельный Лисп был парсером/оптимизатором, вдобавок генерил байт-код для самодельной Forth машины.

Pzz>Будет выглядеть весьма необычно, и заменить того, кто это сделал, другим сотрудником, работодателю будет несколько проблематично.


Проще написать что-нибудь на Scala и сделать сборку через SBT вместо Maven/Gradle. Скалу среднестатический индус не знает.
Как запру я тебя за железный замок, за дубовую дверь окованную,
Чтоб свету божьего ты не видела, мое имя честное не порочила…
М. Лермонтов. Песня про царя Ивана Васильевича, молодого опричника и удалого купца Калашникова
Re: Какие существуют необычные приёмы в Java?
От: Worminator X Россия #StandWithPalestine 🖤🤍💚
Дата: 06.05.22 13:07
Оценка:
Здравствуйте, cppguard, Вы писали:

C>В С++, например, придумали Type lists или CRTP, и вообще много всяких трюков, но в Java самое необычное, что я знаю, это двойная диспечеризация. А какие приёмы вы знаете?


Алгебраические типы и паттерн матчинг на Java через исключения: https://www.linux.org.ru/forum/talks/2449182
Как запру я тебя за железный замок, за дубовую дверь окованную,
Чтоб свету божьего ты не видела, мое имя честное не порочила…
М. Лермонтов. Песня про царя Ивана Васильевича, молодого опричника и удалого купца Калашникова
Re[3]: Какие существуют необычные приёмы в Java?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.05.22 13:51
Оценка:
Здравствуйте, Worminator X, Вы писали:

Pzz>>Ну, можно, например, написать на Java интерпретатор LISP, а на LISP'е содержательную часть программы.


WX>Делал такое, когда писал компилятор на Java. Самодельный Лисп был парсером/оптимизатором, вдобавок генерил байт-код для самодельной Forth машины.


И как, сошло тебе это с рук?
Re: Какие существуют необычные приёмы в Java?
От: maxkar  
Дата: 06.05.22 17:49
Оценка:
Здравствуйте, cppguard, Вы писали:

C> А какие приёмы вы знаете?


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