簡體   English   中英

為什么我們需要在 Java 中處理或拋出已檢查的異常?

[英]Why we need to handle or throw checked exceptions in Java?

我是 Java 的新手,我讀到僅在編譯期間會引發已檢查的異常,即如果存在未處理或未拋出的已檢查異常,則程序將無法成功編譯。 如果某些東西阻止編譯器編譯代碼,那么我們可以刪除它或以另一種方式重新編碼,這樣問題就不存在了。

例如,如果我們試圖打開系統中不存在的文件,我們不應該只打開它。 那么為什么需要處理/拋出這些異常呢?

您在這里的概念問題是您將編譯時發生的事情與運行時發生的事情混為一談; 即當程序由程序員編譯和由用戶運行時。

在編譯時,編譯器分析程序以確定可能拋出的異常。 例如

public static void main(String[] args) {
    FileInputStream fis = new FileInputStream(args[0]);  // HERE
}

FileInputStream(String)構造函數被聲明為throws IOException (查一下。)所以編譯器知道HERE的語句可能會拋出IOException 並且IOException是一個檢查異常。 (查一下。)

它不知道它 它不可能知道它......因為它不知道args[0]將包含什么。 這僅在運行時才知道; 即當程序運行並且用戶提供一些命令行arguments。

問:檢查異常在這里是什么意思?

這意味着main方法要么必須聲明為(例如) throws IOException ,要么必須在try-catch語句中捕獲它。

問:那么為什么是已檢查異常?

因為它是這樣宣布的!

問:為什么會這樣宣布?

強制程序員處理正在打開的文件不存在、不可讀等可能性 當程序(最終)運行時。

編譯器說“對可能發生的事情做點什么……”。


只是重申一下。 編譯器無法檢查文件是否存在,因為它不知道用戶提供什么路徑名。 即使它確實知道,並且它檢查了1該文件在編譯時是否存在,它也不知道該文件是否在運行時仍然存在,可能在不同網絡上的完全不同的機器上......很多年未來。

1 - 這是假設的。 它不檢查。 這將毫無意義。

您不應將異常處理視為問題,而應將其視為一項功能。

假設不存在異常。

var file = new File("test.txt");
if (!file.exists()) {
    file.createNewFile();
}
var writer = new FileWriter(file);
// ...

go 會出現什么問題?

  • 在檢查文件是否存在和打開閱讀器之間,文件可能已被另一個線程/進程刪除。 因此,即使您創建了它,它也消失了->您需要以某種方式鎖定文件
  • 您的 memory 已滿,因此無法創建文件 -> 您需要檢查createNewFile的結果。
  • 該文件存在,但是是一個目錄。
  • 該文件被鎖定,因為另一個進程正在寫入它->您需要檢查它是否正在被寫入。

這樣就可以了(仍然假設沒有例外):

var file = new File("test.txt");
if (!file.exists()) {
    if(file.createNewFile()) {
        if (!file.isDirectory()) {
            if (!isUsed(file)) {
                var writer = new FileWriter(file);
                // ...
            }
        }
    }
}

這是很多代碼,但仍然無法處理第一個問題。

然而

var file = new File("test.txt");
try {
    var writer = new Filewriter(file);
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

更短,更清晰,更容易理解。

此外,通常情況下,如果發生任何這些問題,一切都更有可能正常工作。 因此,與其假設所有最壞的情況並事先進行多次檢查,不如假設最好的情況,如果出現問題,您會尋找原因。

這也會影響運行時。 如果您運行無異常代碼 1000 次,所有這些檢查將運行 1000 次,無論它們是否失敗。 對於異常代碼,情況並非如此,可能根本不會運行。

必須處理 Java 中的已檢查異常,這就是編譯器會抱怨並且沒有編譯代碼的原因。

但是異常本身直到運行時才會引發,以防萬一。

當您編寫代碼時,您應該正確處理所有已檢查的異常,因此您必須編寫一個try catch塊或僅從方法中返回異常。

如果你使用一些引發檢查異常的庫,你可以用我已經解釋過的兩種方式之一來處理。

但是在您的代碼中,您可以選擇使用未經檢查的異常。

可以忽略這些異常,編譯器會很好。 當然,如果在執行時引發了其中一個未經檢查的異常並且沒有被捕獲,您的應用程序將會崩潰。

但這在某些情況下可能是可取的,因為沒有正確的方法來處理 Exception 並且它通常是Error的子類。

無論如何,您不應該考慮如何處理代碼中的錯誤情況,而只考慮異常。

更多: 異常 class錯誤 class

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM