Я искал такое решение:
(более подробно: для некоторого плагина 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
@Ignore
для неиспользуемых параметров универсального типа)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 ) {
// ...
}
}
решения частично найден в других ответах и их недостатки выше:
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 ... ) { ... }
java.lang.Runnable
RuntimeException
, но не проверенныеjava.lang.AutoCloseable
execCode( AutoCloseable code ) { ... code.close() ; ... }
, хотя код не должен ничего делать с семантическим закрывающим контекстом :)java.util.function.Consumer
java.lang.reflect.Method
@Holger хорошо, но это не преимущество / решение для основных требований, особенно потому, что (ГРАММ), а также (Э) не покрыты. (эти execCode( ...)
звонки бывают не только в foo() { ... }
!)
Я просто имею в виду ваш собственный пример; вместо execCode( () -> { System.out.println( "test" ) ; return 0 ; }) ;
можно написать execCode(Executors.callable(() -> System.out.println( "test" )));
Это просто дополнение, а не решение само по себе. Конечно, когда речь идет о проверенных исключениях, можно и нужно прибегать к { statement; return null; }
. Кстати, для void
также есть функциональный интерфейс, позволяющий генерировать исключения, AutoCloseable
, но, возможно, его использование для действий общего назначения может ввести читателя в заблуждение.
@Holger return 0
просто указывает, что могут быть произвольные большие блоки кода с несколькими операторами. относительно AutoClosable
:) разве вы не видели решение (ЮАР), в котором это точно упоминается?
Нет, я не видел. В этом списке легко что-то упустить из виду, поскольку в нем излишне многословно обсуждаются нерешенные вопросы. Например, зачем долго обсуждать java.util.Function
, java.lang.Runnable
и java.util.function.Consumer
, если они не используются из-за отсутствия поддержки исключений? Почему «использование ссылок на методы» вообще рассматривается как решение? Разницы между () -> doBar()
и this::doBar
нет, работает ли она, зависит от функционального интерфейса.
@Holger: если ты не хочешь что-то/кого-то понять, я ничего не могу с собой поделать. Все они являются решениями очень распространенной и общей проблемы, предложенной в списке, и различными решениями. Поиск в Интернете и нахождение такой сжатой информации, как здесь, гораздо более ценно, чем сосредоточение внимания на крошечных различиях одного и того же вопроса. Лучшими ответами для меня и, вероятно, для других являются те, которые не только исправляют мои, возможно, неправильные строки кода, но и исправляют мое мышление о самой проблеме и видение ее в более широком масштабе. Но я согласен, что это мышление не применяется большинством.
@Holger: есть разница между () -> doBar()
и this::doBar
. если вы не знаете, это не значит, что его нет :) попробуйте, как я описал выше, и вы не сможете скомпилировать последний. вы отвечаете на то, чего точно не знаете :-(
«если вы не знаете, это не значит, что его нет». Почему бы вам не просветить нас и рассказать разницу (относящуюся к вашему ответу), о существовании которой вы утверждаете? Ваш «пример» — это просто неполный код, даже синтаксис, указанный в вашем ответе (this::doBar()
), неверен. Легко показать, что () -> doBar()
и this::doBar
работают одинаково хорошо, ideone.com/ftWzfl Если это не соответствует вашему варианту использования, это проблема вашего неполного «примера».
Давайте продолжить обсуждение в чате.
Вы также можете написать
execCode(Executors.callable(() -> System.out.println( "test" )));