【问题标题】:Java skip try catch for throwable fuctionJava跳过可抛出函数的try catch
【发布时间】:2016-02-29 11:13:03
【问题描述】:

我想知道在 Java 中是否有一种方法可以“跳过”我知道不会抛出异常的可抛出函数的 try-catch 方法。

我有这段代码:

DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date date = format.parse(dateString); // <-- Compiler error here
Log.i(PF.TAG, date.toString());

我收到编译器错误,提示未处理异常

Error:(97, 30) 错误:未报告的异常 ParseException;必须被抓住或宣布被扔掉

我可以通过将 format.parse() 放入 try-catch 中来消除此错误。

在 Swift 2 错误处理中,有一个选项可以执行 try! someFunction(),它将编译并执行 throwable 函数并在出现错误时崩溃。

在 Java 中是否有类似的方法,所以我不必将所有我知道不会抛出异常的小任务放在任何地方的 try-catch 中?

【问题讨论】:

  • 在方法名之后抛出 ParseException
  • @FunkDoc23 像这样:Date date = format.parse(dateString) throws ParseException; ?
  • 不,更像是在方法声明之后 - public void parseDate() throws ParseException 但是,如果发生异常,您仍然必须处理它
  • 如果它是您经常使用的操作,您可以将其包装在一个单独的方法调用中,以通用方式处理异常,从而允许您停止为该调用重复样板 try-catch 块

标签: java exception try-catch


【解决方案1】:

并非如此,但您可以编写一个辅助方法来诱使编译器相信已检查的异常是未经检查的。例如:

public static <T> T uncheck(Callable<T> callable) {
  try {
    return callable.call();
  } catch (Throwable t) {
    return rethrow(t);
  }
}

@SuppressWarnings("unchecked")
private static <E extends Throwable, T> T rethrow(Throwable t) throws E {
  throw (E) t;
}

你会这样使用它:

Date date = uncheck(() -> format.parse(dateString));

您还可以将已检查的异常包装到未检查的异常中,就像 jOOL 所做的 here

【讨论】:

  • 我不能使用 Lambda,我必须留在 Java 7 :(
  • @Arbitur 那么你将不得不写一个 try catch 或者让你的方法抛出一个异常......
【解决方案2】:

不是真的。

在 Java 中通常有两种类型的异常 - 已检查(扩展 Exception)或未检查(扩展 RuntimeException)。

以某种方式处理检查的异常是强制性的,不这样做会导致编译时异常,就像你的情况一样。有两种处理方式:

  • 尝试 - 捕获块。如果你愿意,你可以通过提供一个空的 catch 子句和一个有用的注释来忽略,指定为什么这永远不会发生。
    • throws 声明。它是方法声明的一部分,并将处理异常的责任转移给声明方法的客户端。

如果你想模拟你提到的 Swift 结构,你需要的是这样的:

try {
    someFunction()
} catch (Exception e) {
    throw new <some runtime exception>
}

通过这种方式,您“吞下”已检查的异常,停止它的传播,而是抛出一个未检查的运行时异常,这不会强制调用者处理它,并且如果发生原始异常将导致崩溃。

【讨论】:

    【解决方案3】:

    您无法避免在某些时候处理该异常,因为它已被检查,但如果您将调用重构为一个单独的方法来处理例外:

    public class DateUtils {
    
        private DateUtils() { throw new AssertionError(); }
    
        public static Date parse(String toParse, DateFormat format) {
            try {
                return format.parse(toParse);
            catch (ParseException e) {
                // Exception handling code here. Maybe you want to log the error
                // somewhere? Then either re-throw as a RuntimeException or return some
                // default value.
            }
        }
    }
    

    然后你会这样做:

    DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    Date date = DateUtils.parse(dateString, format);
    Log.i(PF.TAG, date.toString());
    

    【讨论】:

    • 更进一步,您可以DateFormat 对象作为常量包含在内 - 但是它们不是线程安全的,因此您必须将其包装在 @ 987654324@。或者,只使用一个包含格式模式的字符串,可能在 enum 内,并在调用期间实例化 DateFormat
    猜你喜欢
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-28
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    相关资源
    最近更新 更多