it-swarm.com.ru

Java 8 Лямбда-функция, которая выдает исключение?

Я знаю, как создать ссылку на метод, который имеет параметр String и возвращает int, это:

Function<String, Integer>

Однако, это не работает, если функция выдает исключение, скажем, оно определено как:

Integer myMethod(String s) throws IOException

Как бы я определил эту ссылку?

384
Triton Man

Вам нужно будет сделать одно из следующего.

  • Если это ваш код, тогда определите свой собственный функциональный интерфейс, который объявляет проверенное исключение

    @FunctionalInterface
    public interface CheckedFunction<T, R> {
       R apply(T t) throws IOException;
    }
    

    и использовать это

    void foo (CheckedFunction f) { ... }
    
  • В противном случае, оберните Integer myMethod(String s) в метод, который не объявляет проверенное исключение:

    public Integer myWrappedMethod(String s) {
        try {
            return myMethod(s);
        }
        catch(IOException e) {
            throw new UncheckedIOException(e);
        }
    }
    

    а потом

    Function<String, Integer> f = (String t) -> myWrappedMethod(t);
    

    или же

    Function<String, Integer> f =
        (String t) -> {
            try {
               return myMethod(t);
            }
            catch(IOException e) {
                throw new UncheckedIOException(e);
            }
        };
    
338
jason

На самом деле вы можете расширить ConsumerFunction и т.д.) Новым интерфейсом, который обрабатывает исключения - используя методы default в Java 8!

Рассмотрим этот интерфейс (расширяет Consumer):

@FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T> {

    @Override
    default void accept(final T elem) {
        try {
            acceptThrows(elem);
        } catch (final Exception e) {
            // Implement your own exception handling logic here..
            // For example:
            System.out.println("handling an exception...");
            // Or ...
            throw new RuntimeException(e);
        }
    }

    void acceptThrows(T elem) throws Exception;

}

Тогда, например, если у вас есть список:

final List<String> list = Arrays.asList("A", "B", "C");

Если вы хотите использовать его (например, с forEach) с некоторым кодом, который генерирует исключения, вы бы традиционно установили блок try/catch:

final Consumer<String> consumer = aps -> {
    try {
        // maybe some other code here...
        throw new Exception("asdas");
    } catch (final Exception ex) {
        System.out.println("handling an exception...");
    }
};
list.forEach(consumer);

Но с этим новым интерфейсом вы можете создать его с помощью лямбда-выражения, и компилятор не будет жаловаться:

final ThrowingConsumer<String> throwingConsumer = aps -> {
    // maybe some other code here...
    throw new Exception("asdas");
};
list.forEach(throwingConsumer);

Или даже просто брось, чтобы быть более лаконичным!

list.forEach((ThrowingConsumer<String>) aps -> {
    // maybe some other code here...
    throw new Exception("asda");
});

Update: Похоже, есть очень полезная часть библиотеки утилит Nice из Durian said Errors , которую можно использовать для решения этой проблемы с гораздо большей гибкостью. Например, в моей реализации выше я явно определил политику обработки ошибок (System.out... или throw RuntimeException), тогда как ошибки Дуриана позволяют применять политику на лету с помощью большого набора утилитарных методов. Спасибо за поделился этим , @NedTwigg !.

Пример использования:

list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c)));
170
jlb

Я думаю класс Дуриана Errors сочетает в себе многие плюсы различных предложений выше.

Чтобы включить Дуриан в ваш проект, вы можете:

  • возьмите его из jcenter или maven central в com.diffplug.durian:durian:3.3.0
  • или просто скопируйте и вставьте в свой код только два небольших класса: Throwing.Java и Errors.Java
55
Ned Twigg

Это не относится к Java 8. Вы пытаетесь скомпилировать что-то эквивалентное:

interface I {
    void m();
}
class C implements I {
    public void m() throws Exception {} //can't compile
}
25
assylias

Отказ от ответственности: я еще не использовал Java 8, только читал об этом.

Function<String, Integer> не генерирует IOException, поэтому вы не можете поместить в него какой-либо код, который throws IOException. Если вы вызываете метод, который ожидает Function<String, Integer>, то лямбда, который вы передаете этому методу, не может выбросить IOException, точку. Вы можете написать лямбда-код следующим образом (я думаю, что это синтаксис лямбды, не уверен):

(String s) -> {
    try {
        return myMethod(s);
    } catch (IOException ex) {
        throw new RuntimeException(ex);
        // (Or do something else with it...)
    }
}

Или, если метод, которому вы передаете лямбду, является тем, который вы написали сами, вы можете определить новый функциональный интерфейс и использовать его в качестве типа параметра вместо Function<String, Integer>:

public interface FunctionThatThrowsIOException<I, O> {
    O apply(I input) throws IOException;
}
11
Adam R. Nelson

Если вы не против использовать стороннюю библиотеку ( Vavr ), вы можете написать

CheckedFunction1<String, Integer> f = this::myMethod;

Он также имеет так называемую монаду Try, которая обрабатывает ошибки:

Try(() -> f.apply("test")) // results in a Success(Integer) or Failure(Throwable)
        .map(i -> ...) // only executed on Success
        ...

Пожалуйста, прочитайте больше здесь .

Отказ от ответственности: я создатель Vavr.

7
Daniel Dietrich

Вы можете использовать Unthrow обертку

Function<String, Integer> func1 = s -> Unthrow.wrap(() -> myMethod(s));

или же

Function<String, Integer> func2 = s1 -> Unthrow.wrap((s2) -> myMethod(s2), s1);
6
SeregaLBN

Вы можете.

Расширяя @marcg UtilException и добавляя универсальный <E extends Exception>, где это необходимо: таким образом, компилятор снова заставит вас добавлять предложения throw и все так, как если бы вы могли изначально генерировать отмеченные исключения в потоках Java 8.

public final class LambdaExceptionUtil {

    @FunctionalInterface
    public interface Function_WithExceptions<T, R, E extends Exception> {
        R apply(T t) throws E;
    }

    /**
     * .map(rethrowFunction(name -> Class.forName(name))) or .map(rethrowFunction(Class::forName))
     */
    public static <T, R, E extends Exception> Function<T, R> rethrowFunction(Function_WithExceptions<T, R, E> function) throws E  {
        return t -> {
            try {
                return function.apply(t);
            } catch (Exception exception) {
                throwActualException(exception);
                return null;
            }
        };
    }

    @SuppressWarnings("unchecked")
    private static <E extends Exception> void throwActualException(Exception exception) throws E {
        throw (E) exception;
    }

}

public class LambdaExceptionUtilTest {

    @Test
    public void testFunction() throws MyTestException {
        List<Integer> sizes = Stream.of("ciao", "hello").<Integer>map(rethrowFunction(s -> transform(s))).collect(toList());
        assertEquals(2, sizes.size());
        assertEquals(4, sizes.get(0).intValue());
        assertEquals(5, sizes.get(1).intValue());
    }

    private Integer transform(String value) throws MyTestException {
        if(value==null) {
            throw new MyTestException();
        }
        return value.length();
    }

    private static class MyTestException extends Exception { }
}
5
PaoloC

Эта проблема беспокоила меня также; Вот почему я создал этот проект .

С этим вы можете сделать:

final ThrowingFunction<String, Integer> f = yourMethodReferenceHere;

Всего имеется 39 интерфейсов, определенных JDK, которые имеют такой Throwing эквивалент; это все @FunctionalInterfaces, используемые в потоках (базовая Stream, но также IntStream, LongStream и DoubleStream).

И так как каждый из них расширяет свой не бросающий аналог, вы можете напрямую использовать их и в лямбдах:

myStringStream.map(f) // <-- works

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

Другие функции также доступны.

4
fge

Однако вы можете создать свой собственный FunctionalInterface, который выдает, как показано ниже.

@FunctionalInterface
public interface UseInstance<T, X extends Throwable> {
  void accept(T instance) throws X;
}

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

import Java.io.FileWriter;
import Java.io.IOException;

//lambda expressions and the execute around method (EAM) pattern to
//manage resources

public class FileWriterEAM  {
  private final FileWriter writer;

  private FileWriterEAM(final String fileName) throws IOException {
    writer = new FileWriter(fileName);
  }
  private void close() throws IOException {
    System.out.println("close called automatically...");
    writer.close();
  }
  public void writeStuff(final String message) throws IOException {
    writer.write(message);
  }
  //...

  public static void use(final String fileName, final UseInstance<FileWriterEAM, IOException> block) throws IOException {

    final FileWriterEAM writerEAM = new FileWriterEAM(fileName);    
    try {
      block.accept(writerEAM);
    } finally {
      writerEAM.close();
    }
  }

  public static void main(final String[] args) throws IOException {

    FileWriterEAM.use("eam.txt", writerEAM -> writerEAM.writeStuff("sweet"));

    FileWriterEAM.use("eam2.txt", writerEAM -> {
        writerEAM.writeStuff("how");
        writerEAM.writeStuff("sweet");      
      });

    FileWriterEAM.use("eam3.txt", FileWriterEAM::writeIt);     

  }


 void writeIt() throws IOException{
     this.writeStuff("How ");
     this.writeStuff("sweet ");
     this.writeStuff("it is");

 }

}
4
JohnnyO

идиома Sneaky throw позволяет обойти CheckedException лямбда-выражения. Обертывание CheckedException в RuntimeException не подходит для строгой обработки ошибок.

Его можно использовать как функцию Consumer , используемую в коллекции Java.

Вот простая и улучшенная версия ответ Джиба .

import static Throwing.rethrow;

@Test
public void testRethrow() {
    thrown.expect(IOException.class);
    thrown.expectMessage("i=3");

    Arrays.asList(1, 2, 3).forEach(rethrow(e -> {
        int i = e.intValue();
        if (i == 3) {
            throw new IOException("i=" + i);
        }
    }));
}

Это просто оборачивает лямбду в rethrow. Это делает CheckedException rethrow любым Exception, который был брошен в вашу лямбду.

public final class Throwing {
    private Throwing() {}

    @Nonnull
    public static <T> Consumer<T> rethrow(@Nonnull final ThrowingConsumer<T> consumer) {
        return consumer;
    }

    /**
     * The compiler sees the signature with the throws T inferred to a RuntimeException type, so it
     * allows the unchecked exception to propagate.
     * 
     * http://www.baeldung.com/Java-sneaky-throws
     */
    @SuppressWarnings("unchecked")
    @Nonnull
    public static <E extends Throwable> void sneakyThrow(@Nonnull Throwable ex) throws E {
        throw (E) ex;
    }

}

Найти полный код и юнит-тесты здесь .

4
myui

У меня была эта проблема с Class.forName и Class.newInstance внутри лямбды, поэтому я просто сделал:

public Object uncheckedNewInstanceForName (String name) {

    try {
        return Class.forName(name).newInstance();
    }
    catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}

Внутри лямбды вместо вызова Class.forName ("myClass"). NewInstance () я просто вызвал uncheckedNewInstanceForName ("myClass")

4
Sergio

Здесь уже опубликовано много отличных отзывов. Просто пытаюсь решить проблему с другой точки зрения. Это только мои 2 цента, пожалуйста, поправьте меня, если я где-то не прав. 

Предложение Throws в FunctionalInterface не очень хорошая идея

Я думаю, что это, вероятно, не очень хорошая идея, чтобы принудительно генерировать IOException по следующим причинам.

  • Это выглядит как анти-паттерн для Stream/Lambda. Вся идея заключается в том, что вызывающая сторона решит, какой код предоставить и как обработать исключение. Во многих сценариях IOException может быть неприменимо для клиента. Например, если клиент получает значение из кеша/памяти вместо фактического ввода-вывода. 

  • Кроме того, обработка исключений в потоках становится действительно отвратительной. Например, вот мой код будет выглядеть, если я использую ваш API

               acceptMyMethod(s -> {
                    try {
                        Integer i = doSomeOperation(s);
                        return i;
                    } catch (IOException e) {
                        // try catch block because of throws clause
                        // in functional method, even though doSomeOperation
                        // might not be throwing any exception at all.
                        e.printStackTrace();
                    }
                    return null;
                });
    

    Ужасно не так ли? Более того, как я уже упоминал в своем первом пункте, метод doSomeOperation может вызывать или не вызывать IOException (в зависимости от реализации клиента/вызывающей стороны), но из-за предложения throws в вашем методе FunctionalInterface мне всегда приходится писать попробуй поймать.

Что мне делать, если я действительно знаю, что этот API выдает IOException

  • Тогда, вероятно, мы путаем FunctionalInterface с типичными интерфейсами. Если вы знаете, что этот API вызовет IOException, то, скорее всего, вам также известно некоторое поведение по умолчанию/абстрактное поведение. Я думаю, что вы должны определить интерфейс и развернуть вашу библиотеку (с реализацией по умолчанию/абстрактно) следующим образом

    public interface MyAmazingAPI {
        Integer myMethod(String s) throws IOException;
    }
    

    Но проблема try-catch все еще существует для клиента. Если я использую ваш API в потоке, мне все равно нужно обрабатывать IOException в отвратительном блоке try-catch.

  • Предоставьте API для потоковой передачи по умолчанию следующим образом

    public interface MyAmazingAPI {
        Integer myMethod(String s) throws IOException;
    
        default Optional<Integer> myMethod(String s, Consumer<? super Exception> exceptionConsumer) {
            try {
                return Optional.ofNullable(this.myMethod(s));
            } catch (Exception e) {
                if (exceptionConsumer != null) {
                    exceptionConsumer.accept(e);
                } else {
                    e.printStackTrace();
                }
            }
    
            return Optional.empty();
        }
    }
    

    Метод по умолчанию принимает в качестве аргумента объект-потребитель, который будет отвечать за обработку исключения. Теперь, с точки зрения клиента, код будет выглядеть так

    strStream.map(str -> amazingAPIs.myMethod(str, Exception::printStackTrace))
                    .filter(Optional::isPresent)
                    .map(Optional::get).collect(toList());
    

    Хорошо, верно? Конечно, вместо Exception :: printStackTrace можно использовать регистратор или другую логику обработки. 

  • Вы также можете предоставить метод, аналогичный https://docs.Oracle.com/javase/8/docs/api/Java/util/concurrent/CompletableFuture.html#exceptionally-Java.util.function.Function- , Это означает, что вы можете предоставить другой метод, который будет содержать исключение из предыдущего вызова метода. Недостатком является то, что вы теперь делаете свои API-интерфейсы с состоянием, что означает, что вам нужно управлять безопасностью потоков, что в конечном итоге приведет к снижению производительности. Просто вариант, чтобы рассмотреть, хотя. 

3
TriCore

Другое решение, использующее упаковку Function, - вернуть либо экземпляр упаковщика вашего результата, скажем, Success, если все прошло хорошо, либо экземпляр, скажем, Failure.

Некоторый код, чтобы уточнить вещи:

public interface ThrowableFunction<A, B> {
    B apply(A a) throws Exception;
}

public abstract class Try<A> {

    public static boolean isSuccess(Try tryy) {
        return tryy instanceof Success;
    }

    public static <A, B> Function<A, Try<B>> tryOf(ThrowableFunction<A, B> function) {
        return a -> {
            try {
                B result = function.apply(a);
                return new Success<B>(result);
            } catch (Exception e) {
                return new Failure<>(e);
            }
        };
    }

    public abstract boolean isSuccess();

    public boolean isError() {
        return !isSuccess();
    }

    public abstract A getResult();

    public abstract Exception getError();
}

public class Success<A> extends Try<A> {

    private final A result;

    public Success(A result) {
        this.result = result;
    }

    @Override
    public boolean isSuccess() {
        return true;
    }

    @Override
    public A getResult() {
        return result;
    }

    @Override
    public Exception getError() {
        return new UnsupportedOperationException();
    }

    @Override
    public boolean equals(Object that) {
        if(!(that instanceof Success)) {
            return false;
        }
        return Objects.equal(result, ((Success) that).getResult());
    }
}

public class Failure<A> extends Try<A> {

    private final Exception exception;

    public Failure(Exception exception) {
        this.exception = exception;
    }

    @Override
    public boolean isSuccess() {
        return false;
    }

    @Override
    public A getResult() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Exception getError() {
        return exception;
    }
}

Простой вариант использования:

List<Try<Integer>> result = Lists.newArrayList(1, 2, 3).stream().
    map(Try.<Integer, Integer>tryOf(i -> someMethodThrowingAnException(i))).
    collect(Collectors.toList());
3
yohan

Вы можете использовать ET для этого. ET - это небольшая библиотека Java 8 для преобразования/перевода исключений.

С ET это выглядит так:

// Do this once
ExceptionTranslator et = ET.newConfiguration().done();

...

// if your method returns something
Function<String, Integer> f = (t) -> et.withReturningTranslation(() -> myMethod(t));

// if your method returns nothing
Consumer<String> c = (t) -> et.withTranslation(() -> myMethod(t));

Экземпляры ExceptionTranslator являются потокобезопасными и могут совместно использоваться несколькими компонентами. Вы можете настроить более конкретные правила преобразования исключений (например, FooCheckedException -> BarRuntimeException), если хотите. Если нет других доступных правил, отмеченные исключения автоматически преобразуются в RuntimeException.

(Отказ от ответственности: я автор ET)

3
micha

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

@FunctionalInterface
public interface FunctionWithException<T, R, E extends Exception> {
    R apply(T t) throws E;
}

Определить как:

private FunctionWithException<String, Integer, IOException> myMethod = (str) -> {
    if ("abc".equals(str)) {
        throw new IOException();
    }
  return 1;
};

И добавьте throws или try/catch к тому же исключению в методе вызывающего.

2
Arpit

Создайте пользовательский тип возврата, который будет распространять проверенное исключение. Это альтернатива созданию нового интерфейса, который отражает существующий функциональный интерфейс с небольшой модификацией «исключения исключения» в методе функционального интерфейса.

Определение

CheckedValueSupplier

public static interface CheckedValueSupplier<V> {
    public V get () throws Exception;
}

CheckedValue

public class CheckedValue<V> {
    private final V v;
    private final Optional<Exception> opt;

    public Value (V v) {
        this.v = v;
    }

    public Value (Exception e) {
        this.opt = Optional.of(e);
    }

    public V get () throws Exception {
        if (opt.isPresent()) {
            throw opt.get();
        }
        return v;
    }

    public Optional<Exception> getException () {
        return opt;
    }

    public static <T> CheckedValue<T> returns (T t) {
        return new CheckedValue<T>(t);
    }

    public static <T> CheckedValue<T> rethrows (Exception e) {
        return new CheckedValue<T>(e);
    }

    public static <V> CheckedValue<V> from (CheckedValueSupplier<V> sup) {
        try {
            return CheckedValue.returns(sup.get());
        } catch (Exception e) {
            return Result.rethrows(e);
        }
    }

    public static <V> CheckedValue<V> escalates (CheckedValueSupplier<V> sup) {
        try {
            return CheckedValue.returns(sup.get());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

Использование

//  Don't use this pattern with FileReader, it's meant to be an
//  example.  FileReader is a Closeable resource and as such should
//  be managed in a try-with-resources block or in another safe
//  manner that will make sure it is closed properly.

//  This will not compile as the FileReader constructor throws
//  an IOException.
    Function<String, FileReader> sToFr =
        (fn) -> new FileReader(Paths.get(fn).toFile());

// Alternative, this will compile.
    Function<String, CheckedValue<FileReader>> sToFr = (fn) -> {
        return CheckedValue.from (
            () -> new FileReader(Paths.get("/home/" + f).toFile()));
    };

// Single record usage
    // The call to get() will propagate the checked exception if it exists.
    FileReader readMe = pToFr.apply("/home/README").get();


// List of records usage
    List<String> paths = ...; //a list of paths to files
    Collection<CheckedValue<FileReader>> frs =
        paths.stream().map(pToFr).collect(Collectors.toList());

// Find out if creation of a file reader failed.
    boolean anyErrors = frs.stream()
        .filter(f -> f.getException().isPresent())
        .findAny().isPresent();

В чем дело?

Добавление «сгенерированных исключений» к каждому функциональному интерфейсу в JDK приведет к нарушению принципа DRY самым ужасным образом. Чтобы избежать этого, создается один функциональный интерфейс, который выдает проверенное исключение (CheckedValueSupplier). Это будет единственный функциональный интерфейс, который позволяет проверять исключения. Все остальные функциональные интерфейсы будут использовать переменную CheckedValueSupplier для переноса любого кода, который выдает проверенное исключение.

Класс CheckedValue будет содержать результат выполнения любой логики, которая выдает проверенное исключение. Это предотвращает распространение проверенного исключения до тех пор, пока код не попытается получить доступ к значению, которое содержит экземпляр CheckedValue.

Проблемы с этим подходом.

  • Сейчас мы выкидываем «Исключение», эффективно скрывая конкретный тип, который был изначально брошен.
  • Мы не знаем, что произошло исключение до вызова CheckedValue#get().

Потребитель и др.

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

Функция вместо потребителя

Одним из подходов является использование функции вместо потребителя, которая применяется при обработке потоков.

    List<String> lst = Lists.newArrayList();
// won't compile
lst.stream().forEach(e -> throwyMethod(e));
// compiles
lst.stream()
    .map(e -> CheckedValueSupplier.from(
        () -> {throwyMethod(e); return e;}))
    .filter(v -> v.getException().isPresent()); //this example may not actually run due to lazy stream behavior

Обострять

Кроме того, вы всегда можете перейти к RuntimeException. Существуют и другие ответы, которые охватывают эскалацию проверенного исключения из Consumer.

Не потреблять.

Просто избегайте функциональных интерфейсов и используйте петлю for в хорошем стиле.

2
justin.hughey

Если вы не возражаете против использования сторонней библиотеки с cyclops-реагировать , библиотекой, в которую я добавляю, вы можете использовать FluentFunctions API для написания

 Function<String, Integer> standardFn = FluentFunctions.ofChecked(this::myMethod);

ofChecked принимает jOOλ CheckedFunction и возвращает смягченную ссылку обратно в стандартную (непроверенную) JDK Java.util.function.Function.

В качестве альтернативы вы можете продолжить работу с захваченной функцией через API FluentFunctions!

Например, чтобы выполнить свой метод, повторить его до 5 раз и записать его статус, вы можете написать 

  FluentFunctions.ofChecked(this::myMethod)
                 .log(s->log.debug(s),e->log.error(e,e.getMessage())
                 .try(5,1000)
                 .apply("my param");
1
John McClean

То, что я делаю, - это разрешаю пользователю давать значение, которое он на самом деле хочет, в случае исключения . Так что я выгляжу примерно так 

public static <T, R> Function<? super T, ? extends R> defaultIfThrows(FunctionThatThrows<? super T, ? extends R> delegate, R defaultValue) {
    return x -> {
        try {
            return delegate.apply(x);
        } catch (Throwable throwable) {
            return defaultValue;
        }
    };
}

@FunctionalInterface
public interface FunctionThatThrows<T, R> {
    R apply(T t) throws Throwable;
}

И тогда это можно назвать как: 

defaultIfThrows(child -> child.getID(), null)
1
mmounirou

Используйте Jool Library или произнесите jOOλ library из JOOQ. Он не только предоставляет непроверенные интерфейсы для обработки исключений, но также предоставляет классу Seq множество полезных методов. 

Кроме того, он содержит функциональные интерфейсы с 16 параметрами. Кроме того, он предоставляет класс Tuple, который используется в различных сценариях.

Джул Гит Линк

В частности, поиск в библиотеке для пакета org.jooq.lambda.fi.util.function. Он содержит все интерфейсы из Java-8 с предварительно установленным флажком. См. Ниже для справки: -

 enter image description here

0
Vinay Prajapati

Я являюсь автором крошечной библиотеки с некоторой общей магией, позволяющей генерировать любые исключения Java в любом месте без необходимости их перехвата или переноса в RuntimeException.

Использование: unchecked(() -> methodThrowingCheckedException())

public class UncheckedExceptions {

    /**
     * throws {@code exception} as unchecked exception, without wrapping exception.
     *
     * @return will never return anything, return type is set to {@code exception} only to be able to write <code>throw unchecked(exception)</code>
     * @throws T {@code exception} as unchecked exception
     */
    @SuppressWarnings("unchecked")
    public static <T extends Throwable> T unchecked(Exception exception) throws T {
        throw (T) exception;
    }


    @FunctionalInterface
    public interface UncheckedFunction<R> {
        R call() throws Exception;
    }

    /**
     * Executes given function,
     * catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
     *
     * @return result of function
     * @see #unchecked(Exception)
     */
    public static <R> R unchecked(UncheckedFunction<R> function) {
        try {
            return function.call();
        } catch (Exception e) {
            throw unchecked(e);
        }
    }


    @FunctionalInterface
    public interface UncheckedMethod {
        void call() throws Exception;
    }

    /**
     * Executes given method,
     * catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
     *
     * @see #unchecked(Exception)
     */
    public static void unchecked(UncheckedMethod method) {
        try {
            method.call();
        } catch (Exception e) {
            throw unchecked(e);
        }
    }
}

источник: https://github.com/qoomon/unchecked-exceptions-Java

0
qoomon

Я сделаю что-то общее:

public interface Lambda {

    @FunctionalInterface
    public interface CheckedFunction<T> {

        T get() throws Exception;
    }

    public static <T> T handle(CheckedFunction<T> supplier) {
        try {
            return supplier.get();
        } catch (Exception exception) {
            throw new RuntimeException(exception);

        }
    }
}

использование:

 Lambda.handle(() -> method());
0
ahll

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

Сделайте этот шаг дальше, и вместо того, чтобы передавать тип исключения, передайте Consumer типа исключения, как в ...

Consumer<E extends Exception>

Вы можете создать несколько вариантов Consumer<Exception> для многократного использования, которые бы покрывали общие потребности вашего приложения в обработке исключений. 

0
Rodney P. Barbati