【问题标题】:Java setOnAction subscribe to event that throws exceptionJava setOnAction 订阅引发异常的事件
【发布时间】:2016-07-28 02:27:17
【问题描述】:

让我先说一下,我不是 Java 程序员,至今无法理解为什么会这样。

我目前正在做一个家庭作业,要求我使用 JavaFX 创建一个基本的 GUI。此 GUI 的功能要求有一些按钮在单击时将执行 CRUD 操作。目前,我的 Insert 方法中的所有内容都已正确设置:

        public void Insert() throws SQLException{

        //Insert new record here
    }

但是,每当我尝试使用“setOnAction”订阅此方法时,编译器都会告诉我该事件存在未处理的异常:

btnInsert.setOnAction(e ->Insert());

我更好奇是否有办法以相对简洁的方式处理这个问题?到目前为止,我一直无法提出解决方案。

【问题讨论】:

    标签: java events javafx


    【解决方案1】:

    这是因为 Java 要求您声明您抛出的所有已检查异常 - 因此,每当您调用可能抛出已检查异常的方法时,您必须要么捕获它,要么声明您可以自己抛出它。

    请参阅this question 以了解已检查与未检查异常的解释(简短版本 - 任何继承 Error 或 RuntimeException 的异常均未检查,而所有其他异常均已检查。)

    当您为setOnAction 提供一个lambda 时,您实际上是在创建EventHandler<ActionEvent> 的匿名类实现。由于它没有声明它会引发任何异常,因此您的匿名类也不会(事实上 - 它不能)。

    所以你有两种解决问题的选择:

    1. 捕获并处理异常:

      btnInsert.setOnAction(e -> {
          try {
              Insert();
          } catch (SQLException ex) {
              // Log error, show error message, etc... Whichever is applicable for your application
          }
      });
      
    2. 重新抛出未经检查的异常:

      btnInsert.setOnAction(e -> {
          try {
              Insert();
          } catch (SQLException ex) {
              throw new RuntimeException(ex); // Or any other subclass of RuntimeException or Error
          }
      });
      

    至于在两个选项之间进行选择 - Oracle's documentation 说:

    以下是底线准则:如果可以合理地期望客户端从异常中恢复,则将其设为已检查异常。如果客户端无法从异常中恢复,请将其设为未经检查的异常。

    当然,这一切都可以从实际的EventHandler 移开,因此可以在无检查异常的方法上调用它。

    【讨论】:

    • 谢谢。这正是我正在寻找的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 2011-11-04
    • 2018-07-24
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多