FXMLLoader.load(url) 抛出的 IOException 不会被捕获

IOException thrown by FXMLLoader.load(url) won't be catched

我正在开发 javaFX 应用程序,我想在应用程序启动时崩溃时 运行 编写一些代码,所以基本上在 FXMLLoader.load() 方法周围的 catch 子句中的 start() 方法中但由于某种原因,它不会捕获它抛出的 IOException。(我在 getResource() 方法中输入了错误的 url 以便抛出异常)

但是,如果我将 IOException 与基础 class Exception 交换,它就可以工作,那么在 IOException 之前是否有更深的嵌套 Exception我不知道? (控制台显示一个java.lang.reflect.InvocationTargetException

更新: 我尝试将 getResource()FXMLoader.load() 函数分开,并用一条消息将它们分开,以查看抛出 Exception 的位置。 结论:ExceptionFXMLLoader.load() 方法 100% 抛出。

public void start(Stage primaryStage) {

    stage = primaryStage;

    try {
        URL url = getClass().getClassLoader().getResource("view/Lgin.fxml");
        System.out.println("URL loaded");
        Parent root = FXMLLoader.load(url);
        System.out.println("FXML loaded");
        stage.setScene(new Scene(null));
        stage.getIcons().add(new Image("resources/icons/Login.png"));
        stage.setTitle("main");
        stage.setResizable(false);
        stage.centerOnScreen();
        stage.show();
    } catch(IOException e) {
        //LOGGER.log(Level.SEVERE, e.toString(), e);
        //System.exit(0);
        System.out.println("catch reached");
    }
}

堆栈跟踪:

URL loaded
Exception in Application start method
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication5(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: Location is required.
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3207)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
    at launcher.DigitalCourt.start(DigitalCourt.java:42)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication12(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait5(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null3(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater4(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null8(WinApplication.java:191)
    ... 1 more
Exception running application launcher.DigitalCourt
Java Result: 1

抛出的异常是 NullPointerException,它不是 IOException 的子类,这就是未捕获异常的原因。

NullPointerException 是一个 RuntimeException 所以如果你想捕捉 NullPointerException 要么捕捉 NullPointerException 要么捕捉 RuntimeException

使用Exception时捕获异常的原因是因为RuntimeException扩展了Exception.

要捕获此特定异常,您可以执行以下任一操作

catch(IOException|NullPointerException e) {
    //LOGGER.log(Level.SEVERE, e.toString(), e);
    //System.exit(0);
    System.out.println("catch reached");
}

catch(IOException|RuntimeException e) {
    //LOGGER.log(Level.SEVERE, e.toString(), e);
    //System.exit(0);
    System.out.println("catch reached");
}

此外,java.lang.reflect.InvocationTargetException 不会从您的代码中抛出,而是从调用您的 public void start(Stage primaryStage) 的 JavaFX 中抛出,因为存在异常 JavaFX 将原始异常包装在 java.lang.reflect.InvocationTargetException