Хороший способ выполнения общих блоков кода в том же контексте обертки, поддерживающий java.lang.Exception без параметров ввода/вывода?

Я искал такое решение:
(более подробно: для некоторого плагина maven, выполняющего другой код сборки в несколько этапов/целей):

  void foo() {

    execCode( () -> doBar() ) ;
    execCode( () -> new File("/baz.txt").create() ) ;
    execCode( () -> { 
      System.out.println( "test" ) ; 
      throw new MojoFailureException("problem 1") ; 
    }) ;
  }


  void execCode( Code code ) throws MojoFailureException {

    try {

      // ... some common initialization / param parsing here ...

      code.run() ;

    } catch( Exception e ) {

      // ... common exception handling throwing e.g. MojoFailureException ...
    }
  }

поддержка (в первую очередь (Э), (ГРАММ) и (С) ниже):

  • (Э): код блокирует выдачу любых java.lang.Exception
  • (В): не требуются входные и выходные значения/объекты
  • (С): короткий, простой для чтения/записи код (минимальный беспорядок)
    • также избегать предупреждений IDE и работать с ними (например, с помощью @Ignore для неиспользуемых параметров универсального типа)
  • (8): поддержка Java 8+
  • (л): никаких дополнительных зависимостей lib/jar, если это возможно (также подойдут очень распространенные, такие как Google Guava или Apache Commons)
  • (ГРАММ): общий контекст (например, некоторые задачи сборки), где можно просто знать, что что-то должно/будет сделано, но должна быть инкапсулирована правильная обработка исключений и другие вещи (общие для каждого вызова).
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Коротко о наилучшей найденной стратегии:

import java.util.concurrent.Callable;

// ...

  void foo() {

    execCode( () -> doBar() ) ;
    execCode( () -> 5 + 2 ) ;
    execCode( () -> { System.out.println( "test" ) ; return 0 ; }) ;
  }


  void execCode( Callable<Object> code ) {

    try {

      code.call() ;

    } catch( Exception e ) {

      // ...
    }
  }

подробнее:

решения частично найден в других ответах и их недостатки выше:

  • (SL): использование java.util.concurrent.Callable (решение выше)
    • соответствует всем вышеперечисленным требованиям
    • также будет хорошо работать с некоторым возвращаемым значением, если это необходимо
  • (С.Ф.): с использованием java.util.Function
    • не поддерживает (Э)
    • особенно с (В) это больше беспорядка ((С)) и семантически запутанно
    • например void foo() { execCode( (i) -> doBar() ) ... void execCode( Function< Void, Void > code ) { ... code.apply( null ) ... }
    • см. также этот ответ
  • (СИ): создание некоторого обычай interface (класс) для его выполнения
    • противоречит (С)
    • например interface Code { abstract void run() throws Exception; }
    • см. также этот ответ
  • (СМ): использование ссылок на методы, таких как this::doBar
    • особый случай, который может быть очень коротким и элегантным, если код (уже) в методе некоторых объектов способствует (С)
    • будет работать с execCode( Callable<Object> ... ) { ... }
    • но не с execCode( Runnable ... ) { ... }
      • противоречит (Э)
    • см. также этот ответ
  • (SR): использование java.lang.Runnable
    • противоречит (Э) и, следовательно, (С), поскольку это позволяет выбрасывать только RuntimeException, но не проверенные
    • см. также этот ответ
  • (ЮАР): использование java.lang.AutoCloseable
    • он соответствует требованиям (Э), (В) и (л), но нуждается хотя бы в некоторых комментариях, чтобы объяснить, почему есть execCode( AutoCloseable code ) { ... code.close() ; ... }, хотя код не должен ничего делать с семантическим закрывающим контекстом :)
  • (SC): использование java.util.function.Consumer
    • не поддерживает (Э)
    • см. также этот ответ* (С.Х): использование java.lang.reflect.Method
    • противоречило бы особенно (С)
    • см. также этот ответ
  • (С.7): решение шаблон команды
    • если он должен быть совместим с Java 7 (противоречит (8)), этот ответ с шаблоном команды может быть хорошим решением

Вы также можете написать execCode(Executors.callable(() -> System.out.println( "test" )));

Holger 22.03.2022 08:11

@Holger хорошо, но это не преимущество / решение для основных требований, особенно потому, что (ГРАММ), а также (Э) не покрыты. (эти execCode( ...) звонки бывают не только в foo() { ... }!)

Andreas Covidiot 23.03.2022 11:37

Я просто имею в виду ваш собственный пример; вместо execCode( () -> { System.out.println( "test" ) ; return 0 ; }) ; можно написать execCode(Executors.callable(() -> System.out.println( "test" ))); Это просто дополнение, а не решение само по себе. Конечно, когда речь идет о проверенных исключениях, можно и нужно прибегать к { statement; return null; }. Кстати, для void также есть функциональный интерфейс, позволяющий генерировать исключения, AutoCloseable, но, возможно, его использование для действий общего назначения может ввести читателя в заблуждение.

Holger 23.03.2022 11:45

@Holger return 0 просто указывает, что могут быть произвольные большие блоки кода с несколькими операторами. относительно AutoClosable :) разве вы не видели решение (ЮАР), в котором это точно упоминается?

Andreas Covidiot 23.03.2022 11:48

Нет, я не видел. В этом списке легко что-то упустить из виду, поскольку в нем излишне многословно обсуждаются нерешенные вопросы. Например, зачем долго обсуждать java.util.Function, java.lang.Runnable и java.util.function.Consumer, если они не используются из-за отсутствия поддержки исключений? Почему «использование ссылок на методы» вообще рассматривается как решение? Разницы между () -> doBar() и this::doBar нет, работает ли она, зависит от функционального интерфейса.

Holger 23.03.2022 11:59

@Holger: если ты не хочешь что-то/кого-то понять, я ничего не могу с собой поделать. Все они являются решениями очень распространенной и общей проблемы, предложенной в списке, и различными решениями. Поиск в Интернете и нахождение такой сжатой информации, как здесь, гораздо более ценно, чем сосредоточение внимания на крошечных различиях одного и того же вопроса. Лучшими ответами для меня и, вероятно, для других являются те, которые не только исправляют мои, возможно, неправильные строки кода, но и исправляют мое мышление о самой проблеме и видение ее в более широком масштабе. Но я согласен, что это мышление не применяется большинством.

Andreas Covidiot 24.03.2022 12:32

@Holger: есть разница между () -> doBar() и this::doBar. если вы не знаете, это не значит, что его нет :) попробуйте, как я описал выше, и вы не сможете скомпилировать последний. вы отвечаете на то, чего точно не знаете :-(

Andreas Covidiot 24.03.2022 12:37

«если вы не знаете, это не значит, что его нет». Почему бы вам не просветить нас и рассказать разницу (относящуюся к вашему ответу), о существовании которой вы утверждаете? Ваш «пример» — это просто неполный код, даже синтаксис, указанный в вашем ответе (this::doBar()), неверен. Легко показать, что () -> doBar() и this::doBar работают одинаково хорошо, ideone.com/ftWzfl Если это не соответствует вашему варианту использования, это проблема вашего неполного «примера».

Holger 24.03.2022 12:53

Давайте продолжить обсуждение в чате.

Andreas Covidiot 24.03.2022 13:13

Другие вопросы по теме