代码之家  ›  专栏  ›  技术社区  ›  Anonymous Creator

没有try-catch的回调中的未处理异常类型[重复]

  •  0
  • Anonymous Creator  · 技术社区  · 5 年前

    我知道如何创建对一个方法的引用,该方法具有 String 参数并返回 int ,它是:

    Function<String, Integer>
    

    但是,如果函数抛出异常,例如定义为:

    Integer myMethod(String s) throws IOException
    

    我该如何定义这个引用?

    0 回复  |  直到 8 年前
        1
  •  536
  •   Simeon Leyzerzon mthmulders    7 年前

    您需要执行以下操作之一。

    • 如果是你的代码,那么定义你自己的函数接口来声明选中的异常:

      @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);
              }
          };
      
        2
  •  243
  •   Sergey Vyacheslavovich Brunov prodigitalson    3 年前

    你实际上可以扩展 Consumer (以及 Function 等等),使用Java 8的新接口处理异常 默认方法 !

    考虑此接口(扩展 消费者 ):

    @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);
    

    但是有了这个新接口,你可以用lambda表达式实例化它,编译器不会抱怨:

    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");
    });
    

    更新

    看起来有一个非常好的实用程序库部分 Durian 打电话 Errors 这可以更灵活地用于解决这个问题。例如,在上面的实现中,我明确定义了错误处理策略( System.out... throw RuntimeException ),而Durian's Errors允许您通过一整套实用方法动态应用策略。谢谢 sharing it @NedTwigg!。

    示例用法:

    list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c)));
    
        3
  •  70
  •   Community Mohan Dere    9 年前

    我想 Durian's Errors class 结合了上述各种建议的许多优点。

    要将榴莲纳入您的项目,您可以:

        4
  •  33
  •   assylias    13 年前

    这不是Java 8特有的。您正试图编译相当于以下内容的东西:

    interface I {
        void m();
    }
    class C implements I {
        public void m() throws Exception {} //can't compile
    }
    
        5
  •  13
  •   Adam R. Nelson    13 年前

    免责声明:我还没有使用过Java 8,只读过它。

    Function<String, Integer> 不扔 IOException ,所以你不能在里面放任何代码 throws IOException .如果你调用的方法需要 功能<字符串,整数> ,则传递给该方法的lambda不能抛出 IO异常 ,期间。你可以这样写一个lambda(我认为这是lambda语法,不确定):

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

    或者,如果你传递lambda的方法是你自己编写的,你可以定义一个新的函数接口,并将其用作参数类型,而不是 功能<字符串,整数> :

    public interface FunctionThatThrowsIOException<I, O> {
        O apply(I input) throws IOException;
    }
    
        6
  •  11
  •   nob Daniel Dietrich    9 年前

    如果你不介意使用第三方库( Vavr )你可以写

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

    它还具有所谓的Try monad,用于处理错误:

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

    请阅读更多 here .

    免责声明:我是Vavr的创建者。

        7
  •  10
  •   Neuron MonoThreaded    8 年前

    Sneaky throw idiom 允许绕过 CheckedException Lambda表达式。包裹a CheckedException 在一个 RuntimeException 不利于严格的错误处理。

    它可以用作 Consumer Java集合中使用的函数。

    这是一个简单而改进的版本 jib's answer .

    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);
            }
        }));
    }
    

    这只是将lambda封装在一个 重新思考 它使 CheckedException 重新抛出任何 Exception 它被扔进了你的lambda中。

    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;
        }
    
    }
    

    查找完整的代码和单元测试 here .

        8
  •  7
  •   JohnnyO    11 年前

    但是,您可以创建自己的Functional Interface,如下所示。。

    @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");
    
     }
    
    }
    
        9
  •  7
  •   SeregaLBN    10 年前

    您可以使用 unthrow wrapper

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

    Function<String, Integer> func2 = s1 -> Unthrow.wrap((s2) -> myMethod(s2), s1);
    
        10
  •  6
  •   PaoloC    11 年前

    你可以。

    扩展@margg的 UtilException 并添加通用 <E extends Exception> 必要时:这样,编译器将再次强制您添加throw子句和所有内容,就像您可以在java8的流上本机抛出已检查的异常一样。

    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 { }
    }
    
        11
  •  5
  •   Sergio    11 年前

    我在lambda内部的Class.forName和Class.newInstance中遇到了这个问题,所以我只是这样做了:

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

    在lambda内部,我没有调用Class.forName(“myClass”).newInstance(),而是调用了uncheckedNewInstanceForName(“myClass”)

        12
  •  5
  •   justin.hughey    7 年前

    创建一个自定义返回类型,用于传播已检查的异常。这是创建一个新接口的替代方案,该新接口通过对功能接口方法的“抛出异常”进行轻微修改来镜像现有的功能接口。

    定义

    CheckedValue供应商

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

    检查值

    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();
    

    发生什么事?

    创建了一个抛出已检查异常的单一功能接口( CheckedValueSupplier ). 这将是唯一允许检查异常的功能接口。所有其他功能接口将利用 CheckedValue供应商 包装任何抛出已检查异常的代码。

    这个 CheckedValue 类将保存执行任何抛出已检查异常的逻辑的结果。这可以防止已检查异常的传播,直到代码尝试访问某个实例的值 检查值 包含。

    这种方法的问题。

    • 我们现在抛出“Exception”有效地隐藏了最初抛出的特定类型。
    • 我们不知道发生了异常,直到 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 。还有其他答案涵盖了从内部升级已检查的异常 消费者 .

    不要消费。

    只需避免使用功能接口,并使用一个好的老式for循环。

        13
  •  4
  •   yohan    12 年前

    使用Function包装器的另一种解决方案是,如果一切顺利,返回结果包装器的实例,比如Success,或者返回失败的实例。

    一些代码来澄清事情:

    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());
    
        14
  •  4
  •   fge    11 年前

    这个问题也一直困扰着我;这就是我创造的原因 this project .

    有了它,你可以做到:

    final ThrowingFunction<String, Integer> f = yourMethodReferenceHere;
    

    JDK定义了总共39个接口,它们具有这样的特性 Throwing 等效;这些都是 @FunctionalInterface s用于流(基础 Stream 而且 IntStream , LongStream DoubleStream ).

    当它们中的每一个都扩展了它们的非投掷对应项时,你也可以直接在lambdas中使用它们:

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

    默认行为是,当你抛出lambda抛出一个选中的异常时 ThrownByLambdaException 以选中的异常作为原因抛出。因此,您可以捕捉到这一点并找出原因。

    其他功能也可用。

        15
  •  4
  •   TriCore    10 年前

    这里已经发布了很多很棒的回复。只是试图从不同的角度解决问题。这只是我的2美分,如果我哪里错了,请纠正我。

    Functional Interface中的Throws子句不是一个好主意

    我认为强制抛出IOException可能不是一个好主意,原因如下

    • 在我看来,这与Stream/Lambda的模式相反。整个想法是,调用者将决定提供什么代码以及如何处理异常。在许多情况下,IOException可能不适用于客户端。例如,如果客户端从缓存/内存中获取值,而不是执行实际的I/O。

    • 此外,流中的异常处理变得非常可怕。例如,如果我使用您的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(取决于客户端/调用者的实现),但由于Functional Interface方法中的throws子句,我总是必须编写try-catch。

    如果我真的知道这个API抛出IOException,该怎么办

    • 那么,我们可能会将Functional Interface与典型的接口混淆。如果您知道这个API会抛出IOException,那么您很可能也知道一些默认/抽象行为。我认为你应该定义一个接口并部署你的库(使用默认/抽象实现),如下所示

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

      但是,客户端仍然存在try-catch问题。如果我在流中使用您的API,我仍然需要在可怕的try-chatch块中处理IOException。

    • 提供一个默认的流友好型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有状态,这意味着你需要处理线程安全,这最终会影响性能。不过,这只是一个值得考虑的选择。

        16
  •  4
  •   Arpit Aggarwal    9 年前

    默认情况下,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 调用者方法中也有同样的异常。

        17
  •  4
  •   Stephen Paul    6 年前

    我使用了一个重载的实用函数,名为 unchecked() 它处理多个用例。


    一些常见用法

    unchecked(() -> new File("hello.txt").createNewFile());
    
    boolean fileWasCreated = unchecked(() -> new File("hello.txt").createNewFile());
    
    myFiles.forEach(unchecked(file -> new File(file.path).createNewFile()));
    

    配套公用设施

    public class UncheckedUtils {
    
        @FunctionalInterface
        public interface ThrowingConsumer<T> {
            void accept(T t) throws Exception;
        }
    
        @FunctionalInterface
        public interface ThrowingSupplier<T> {
            T get() throws Exception;
        }
    
        @FunctionalInterface
        public interface ThrowingRunnable {
            void run() throws Exception;
        }
    
        public static <T> Consumer<T> unchecked(
                ThrowingConsumer<T> throwingConsumer
        ) {
            return i -> {
                try {
                    throwingConsumer.accept(i);
                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
            };
        }
    
        public static <T> T unchecked(
                ThrowingSupplier<T> throwingSupplier
        ) {
            try {
                return throwingSupplier.get();
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
    
        public static void unchecked(
                ThrowingRunnable throwing
        ) {
            try {
                throwing.run();
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
    }
    
        18
  •  3
  •   Community Mohan Dere    6 年前

    您可以使用 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的作者)

        19
  •  3
  •   John McClean    10 年前

    如果你不介意使用第三方库 cyclops-react ,我贡献的一个图书馆,你可以使用 FluentFunctions API编写

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

    ofChecked接受一个jOO CheckedFunction,并将软化的引用返回给标准(未选中)JDK java.util.function。功能。

    或者,您可以通过FluentFunctions api继续使用捕获的函数!

    例如,要执行您的方法,最多重试5次,并记录您可以写入的状态

      FluentFunctions.ofChecked(this::myMethod)
                     .log(s->log.debug(s),e->log.error(e,e.getMessage())
                     .try(5,1000)
                     .apply("my param");
    
        20
  •  2
  •   mmounirou    11 年前

    我所做的是允许用户在出现异常时给出他真正想要的值。 所以我有一个像这样的东西

    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)
    
        21
  •  1
  •   Vinay Prajapati Mahfujur Rahman    8 年前

    使用 Jool Library 或者说 jOOλ library JOOQ 它不仅提供了未经检查的异常处理接口,还为Seq类提供了许多有用的方法。

    此外,它还包含最多16个参数的功能接口。此外,它还提供了用于不同场景的Tuple类。

    Jool Git Link

    特别是在库查找中 org.jooq.lambda.fi.util.function 包裹。它包含了Java-8中所有带有Checked前缀的接口。参考如下:-

    enter image description here

        22
  •  1
  •   lbenedetto    5 年前

    如果你有lombok,你可以用@SneakyThrows注释你的方法

    SneakyThrow不会默默地吞下、包装到RuntimeException中,也不会以其他方式修改所列已检查异常类型的任何异常。JVM不检查所检查的异常系统的一致性;javac确实如此,这个注释允许您选择退出其机制。

    https://projectlombok.org/features/SneakyThrows

        23
  •  0
  •   Rodney P. Barbati    9 年前

    所提供的几个解决方案使用E的通用参数来传递抛出的异常类型。

    更进一步,而不是传入异常类型,传入异常类型的Consumer,如。。。

    Consumer<E extends Exception>
    

    您可以创建几个可重复使用的变体 Consumer<Exception> 这将涵盖应用程序的常见异常处理需求。

        24
  •  0
  •   ahll    9 年前

    我将做一些通用的事情:

    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());
    
        25
  •  0
  •   qoomon    7 年前

    我是一个小库的作者,这个库有一些通用的魔法,可以在任何地方抛出任何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

        26
  •  0
  •   Stephan Zehnder    4 年前

    对我来说,首选的解决方案是使用龙目岛。不管怎样,这是一个不错的图书馆。

    而不是:

    Integer myMethod(String s) throws IOException
    

    你会有

    import lombok.SneakyThrows;
    
    @SneakyThrows
    Integer myMethod(String s)
    

    异常仍然被抛出,但您不需要用throws声明它。

        27
  •  -8
  •   Jamal Tom_B    11 年前
    public void frankTest() {
        int pageId= -1;
    
        List<Book> users= null;
        try {
            //Does Not Compile:  Object page=DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> new Portal(rw.getInt("id"), "", users.parallelStream().filter(uu -> uu.getVbid() == rw.getString("user_id")).findFirst().get(), rw.getString("name")));
    
            //Compiles:
            Object page= DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> { 
                try {
                    final Book bk= users.stream().filter(bp -> { 
                        String name= null;
                        try {
                            name = rw.getString("name");
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        return bp.getTitle().equals(name); 
                    }).limit(1).collect(Collectors.toList()).get(0);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return new Portal(rw.getInt("id"), "", users.get(0), rw.getString("name")); 
            } );
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }