IOException 当我尝试捕获时说永远不会被抛出?

时间:2021-05-20 20:16:02

标签: java io ioexception

这是我的代码:

    @Override
    public void start(Stage primaryStage) throws FileNotFoundException {
        System.out.print("Url gui successfully started.");
        final HBox hBox = new HBox();
        hBox.setSpacing(5);

        final TextField urlTextField = new TextField();
        urlTextField.setPromptText("Type Url Here");
        Button unblock = new Button("Unblock");
        Button block = new Button("Block");

        String hostsFile = BlockAndUnblock.getHostsFile();
        String blockedUrls = BlockAndUnblock.getBlockedUrls();
        boolean inSession = InSession.inSession > 0;
        try {
            unblock.setOnAction(event -> BlockAndUnblock.blockSite(hostsFile,blockedUrls,urlTextField.getText(), inSession));
            block.setOnAction(event -> BlockAndUnblock.unBlockSite(hostsFile,blockedUrls,urlTextField.getText(), inSession));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("You encountered an IOException when trying to initiate the block and unblock buttons.");
        }

        ArrayList<String> urls = new ArrayList<String>();
        urls = readUrls();
        ListView listView = new ListView();
        listView.setId("Listview");
        for (String s: urls) {
            listView.getItems().add(s);
        }

        hBox.getChildren().add(listView);
        hBox.getChildren().add(urlTextField);
        hBox.getChildren().add(block);
        hBox.getChildren().add(unblock);
        hBox.setAlignment(Pos.CENTER_LEFT);
        hBox.setId("Urls");

        Scene scene = new Scene(hBox, 750, 500);
        scene.getStylesheets().addAll(this.getClass().getResource("../style.css").toExternalForm());
        primaryStage.setTitle("Urls");
        primaryStage.setScene(scene);

        primaryStage.show();
    }

它调用的阻止和解除阻止方法如下:

    public static void unBlockSite(String hostsFile, String blockedUrls, String url, boolean inSession) throws IOException {
        String file = Files.readString(Paths.get(hostsFile));
        file = file.replace("0.0.0.0 " + url.substring(url.indexOf("//") + 2,url.length()-1) +"\n","");
        file = file.replace("::0 " + url.substring(url.indexOf("//") + 2,url.length()-1) +"\n","");
        Files.writeString(Paths.get(blockedUrls), file, StandardOpenOption.TRUNCATE_EXISTING);
        if (inSession) {
            unBlock(hostsFile);
            block(hostsFile, blockedUrls);
        }
    }
    public static void blockSite(String hostsFile, String blockedUrls, String url, boolean inSession) throws IOException {
        if (inSession) unBlock(hostsFile);
        Files.writeString(Paths.get(blockedUrls), "0.0.0.0 " + url.substring(url.indexOf("//") + 2,url.length()-1) +"\n", StandardOpenOption.APPEND);
        Files.writeString(Paths.get(blockedUrls), "::0 " + url.substring(url.indexOf("//") + 2,url.length()-1) +"\n", StandardOpenOption.APPEND);
        if (inSession) block(hostsFile, blockedUrls);
    }

这是我得到的错误:

<块引用>

site\java\BlockUrlsMenu.java:37: 错误:未报告的异常 IOException;必须被捕获或声明被抛出 unblock.setOnAction(event -> BlockAndUnblock.blockSite(hostsFile,blockedUrls,urlTextField.getText(), inSession)); ^

<块引用>

site\java\BlockUrlsMenu.java:38: 错误:未报告的异常 IOException;必须被捕获或声明被抛出 block.setOnAction(event -> BlockAndUnblock.unBlockSite(hostsFile,blockedUrls,urlTextField.getText(), inSession)); ^

<块引用>

site\java\BlockUrlsMenu.java:39: 错误:在相应的 try 语句的主体中永远不会抛出异常 IOException } catch (IOException e) { ^

<块引用>

3 个错误

令我困惑的是,显然 BlockAndUnblock 要求我事先捕获或抛出 IOException,但是当我将它们包围在 try{} catch{} 方法中时,它说它们永远不会抛出 IOException。我还尝试将 start() 方法的所有内容放入 try{} catch{} 块中,但它仍然给了我前两个错误。

为什么它告诉我捕获一个 IOException 然后说它不会抛出一个?

感谢您的帮助,我知道这是很多代码。

1 个答案:

答案 0 :(得分:0)

代码很多,所以我的分析可能很肤浅,但我认为这是因为 .setOnAction() 采用 Lambda 表达式。

Lambdas 不能抛出像 IOException 这样的检查异常(因此 catch 块变得无效并且你得到第三个错误,因为两个 lambdas 实际上不能抛出),但同时您的 lambda 表达式正在调用两个函数,它们会抛出一个 IOException,而您没有在 lambda 中捕获它们(因此您会得到第一个和第二个错误)。

尝试改变这一点:

try {
    unblock.setOnAction(event - > BlockAndUnblock.blockSite(hostsFile, blockedUrls, urlTextField.getText(), inSession));
    block.setOnAction(event - > BlockAndUnblock.unBlockSite(hostsFile, blockedUrls, urlTextField.getText(), inSession));
} catch (IOException e) {
    e.printStackTrace();
    System.out.println("You encountered an IOException when trying to initiate the block and unblock buttons.");
}

...进入这个:

try {
    unblock.setOnAction(event - > {
            try {
                BlockAndUnblock.blockSite(hostsFile, blockedUrls, urlTextField.getText(), inSession));
        }
        catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    block.setOnAction(event - > {
            try {
                BlockAndUnblock.unBlockSite(hostsFile, blockedUrls, urlTextField.getText(), inSession));
        }
        catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
} catch (RuntimeException e) {
    e.printStackTrace();
    System.out.println("You encountered an IOException when trying to initiate the block and unblock buttons.");
}

使用上述内容,在每个 lambda 中,您捕获 IOException 并将其包装在 RuntimeException 中(这是未选中的,因此可以由 lambda 抛出)。 在外部 catch 中,您捕获 RuntimeException 并使用 IOException

执行您最初想做的任何事情