JavaRush /Java Blog /Random-TW /Java 中的異常
Roman
等級 33

Java 中的異常

在 Random-TW 群組發布
當我遇到「例外」這個主題時,出現了許多問題,我必須在網路的各個角落尋找答案,才能詳細了解它是如何運作的。因此,我整理了自己的解釋,對於剛遇到這種現象的初學者來說可能更容易理解。 Java 中的異常 - 1在電腦中,中斷是向處理器發出的傳入訊號,表示正在發生需要立即回應的事件。中斷訊號要求處理器暫停正在運行的程序,以便稍後可以繼續運行,也就是說,電腦必須記住與程式執行相關的所有資訊。這種中斷即使不是致命的,也是暫時的。此類中斷可能是由程式碼或某些硬體功能引起的(例如,簡單地按鍵盤上的按鍵;例如,自動關閉電腦的計時器)。中斷的數量被限制在一定數量,內置於特定處理器的生產中,也就是說,為此分配了特殊的通信“通道”,允許您繞過所有其他進程來訪問處理器。 當執行程式程式碼中發生錯誤時(例如,發生被零除的錯誤),也會自動產生中斷。這種中斷傳統上稱為陷阱或異常。在這種情況下,習慣上說:“異常被拋出”,即觸發了異常或拋出了異常(拋出),即請求中斷帶著「做什麼?」的問題 發送到處理器。此時,處理器停止工作,記住它停止的點,或者更確切地說是下一個單元的簇,必須執行該資訊。已執行和未執行的指令的整個鏈都會被記住。之後,處理器會從記憶體中讀取指令,以便在發生此類錯誤時採取行動。根據這條指令,它可以將新的值輸入到某些簇中,添加一些動作鍊或一個新的循環(例如,返回或循環循環)等,即根據錯誤,先前放置執行向下指令。電腦系統本身內建了許多自動中斷,這些中斷在一定時間後被觸發,例如,控制電腦上運行的進程或運行設定的警報、收集傳入的外部信號以及各種數據轉換器。值得記住的是,由於多種原因,大量中斷可能會導致系統完全「掛起」。程式碼中的錯誤將自動導致處理器中斷,處理器將嘗試根據規定的指令進行處理。但並不是所有的中斷都是為了處理它們而設計的,否則它可能會產生一個不適合我們的程序,例如,它只會使應用程式崩潰。因此,在程式設計時,可以為程式設計師可能看到錯誤可能性的特定程式碼段組織自己的中斷。在這種情況下,錯誤將在程式內進行處理,並且不會聯絡處理器來取得處理指令。此類區塊的定義是透過建立「異常」物件來組織的。該物件是在區塊中自動建立的try-catch。檢查該區塊>try是否有錯誤,如果有錯誤,程式將轉到 區塊catch,在此採取措施來防止或消除錯誤。例如,如果我們從鍵盤輸入數字,隨後必須進行加減法,那麼從鍵盤輸入字母將無法將它們與數字相加(我們用字母 S 表示這兩個變數的和)。因此,作為一個團隊,try我們必須檢查包含數字的數字 A 是否可以與包含字母的數字 B 相加(即 S = A + B),如果這不可能,並且不可能,那麼一定必須採取措施,確保錯誤不會發生,並且帶有“做什麼?”問題的新中斷不會飛至處理器。如果程式中沒有異常,則其執行將被處理器中斷。如果出現異常,當它被命令「捕獲」時try,控制權傳遞給命令catch,命令可以設定替代解決方案,例如,我們不會將這兩個數字相加,而是設定S = A。
int a = 4;
String b = “hello”;
int S = 0;
 try {
   S = a + b;
   int r = 1;
 } catch (Exception igogo1) {
   S = a;
 }
 return S;
/* 字串“int r = 1;” 由於發生錯誤而未執行,且程式將工作直接重定向到異常處理程序(catch 區塊*/)因此,異常的存在是解決程式內問題的機會,而無需將其拋出到處理器層級。當偵測到錯誤時,在區塊中自動建立的「Exception」物件try包含錯誤類型的值。我們稱之為「OurException」——針對我們的具體情況,並描述我們的具體錯誤。Java語言的創建者預先創建了一定的典型錯誤列表以及糾正這些錯誤的典型選項,也就是說,在java中存在一定的異常庫,我們可以利用它來處理已經發生的錯誤,以便不要自己編寫處理程式碼,因此OurException 很可能已經有人被描述過,因此我們只需要知道要將哪些異常的名稱插入到我們的程式中以處理可能發生故障的程式碼。如果我們犯了錯誤並從庫中選擇了不正確的異常,那麼處理程序將不會「捕獲」它,該錯誤將不會在程式中找到解決方案,並且請求將被發送到處理器。但對於懶人來說,有個方法。如果我們不知道庫中需要的異常的名稱,那麼我們可以使用名稱為「Exception」的通用異常,如上面的範例所示。此異常能夠處理任何類型的錯誤,但它無法提供我們可以記錄的有關事件的特定資訊。先前編寫的異常庫由已檢查和未檢查的異常組成。可檢查的是那些可以在不中斷程式工作的情況下進行糾正的文件,也就是說,如果我們嘗試打開不存在的資料夾中的文件,系統會讓我們知道,我們可以刪除該文件進入所需的資料夾並繼續程序。也就是說,事實上,一個中斷請求被發送到處理器,但沒有問:“看看如何解決這個問題?!?!” 我們發送了一個中斷,這是我們自己檢測到的,帶有一條現成的指令,處理器處理該指令並繼續執行程式。未檢查的是那些無法糾正的錯誤,程式將在完成之前關閉,即向處理器發送中斷請求,無論如何都會中斷程式的執行。在程式中編寫此類異常的唯一目的是讓用戶了解發生了什麼,因為捕獲此中斷後,我們可以在螢幕上顯示一條訊息訊息,導致程式崩潰。捕獲此類中斷的第二個原因是能夠將它們記錄在日誌中以供後續分析(您被駭客攻擊了,但至少您知道在哪裡)。存在此類庫的結果是需要記住包含它們。(例如,可以在此處找到帶有庫的已檢查和未檢查異常的列表)如果我們不確切知道要包含哪個庫或有多個錯誤選項,那麼我們可以catch在多個中列出所需的異常。如果清單中存在正確的處理程序,系統本身將選擇它。您可以編寫一個通用的“異常”來代替特定的異常,它可以處理任何類型的異常(如果它在先前的區塊中未處理)。
int a = 4;
String b = “hello”;
int S = 0;
 try {
   S = a + b;
   int r = 1;
 }
catch(NullPointerException blabla2) {
   System.out.println("Exception handling code for the NullPointerException.");
 }
catch (ArithmeticException ex1) {
   S = a;
 }
catch(Exception uups1) {
   System.out.println("Exception occured");
 }
 return S;
如果存在區塊,try則會自動建立異常。如果我們需要在某個時間點強制出現異常,則可以使用該指令throw。也就是說,我們獨立建立一個物件new throw......之後,程式停止工作,向處理器發送中斷請求並轉移到程式部分catch,從那裡嘗試獲取進一步操作的指令。透過手動建立Exception,我們可以從庫中指定其特定類型:

throw new ArithmeticException("Access denied - You must be at least 18 years old.");
那麼處理程序將搜尋catch具有此特定異常的區塊- 在整個程式中搜尋所有方面catch。在throw異常處理命令之後,除了區塊中的程式碼之外,所有剩餘的程式碼將不會被執行catch。如果在程式中找不到處理程序,則會向處理器詢問以下問題:“自己決定要做什麼”,然後它會中斷程式。呼叫...可以在區塊內部和外部(程式中的任何位置) new throw進行>try
try {
   /* функция or действие, в котором есть сомнения. То есть: «попробуй выполнить это, а если не получится, а, если не получится, запускай режим исключения» */
   throw new CallForException(); /* Назначаем исключение, которое будет работать в случае наличия ошибки в функции, описанной выше. Здесь исключение «CallForException» - берется из библиотеки существующих исключений */
} catch (CallForException ee1) {
   /* Корректируем ошибку, чтобы программа не «отвалилась» or выводим сообщение об ошибке or что-то ещё */
} finally {
   /* этот блок работает всегда независимо от того была ошибка or нет. А если была, то сработало ли решение в catch or нет */
   /* часто используется для подчистки хвостов, например, для закрытия запущенного file or базы данных */
   /* в ряде случаев блок catch вообще может быть опущен и оставлен только блок finally и наоборот finally может быть опущен и оставлен только catch */
   /* Не допускается использование этого блока в ряде случаев, например, когда функция System.exit() запущена or другие системные Исключения, типа «отключение электроэнергии» и т.п. */
}

例外情況通知

以前由某人編寫的方法可能包括拋出異常。為了保險起見,編寫程式碼的程式設計師警告後來的程式設計師,他寫的方法可能會出現錯誤。因此,例如下面描述的文件建立方法規定在建立文件時可能會發生錯誤(給定路徑沒有文件),這意味著需要一個錯誤處理程序:
public void createFile(String path, String text) throws IOException {
    FileWriter writer = new FileWriter(path, true);
    writer.write(text);
    writer.close();
}
但同時,沒有處理程序本身,這意味著現在我們將無法在正常模式下簡單地呼叫程式中編寫的方法。現在我們必須編寫一個錯誤處理程序並在區塊中呼叫此方法try
String filePath = "hello.txt";
String text = "Hello World";

try {
    createFile(filePath, text);
} catch (IOException ex) {
    System.err.println("Error creating file: " + ex);
}

本機異常

如果現有的程式庫不足以滿足我們的需求,則可以編寫自己的異常來處理某些錯誤。為此,我們只需建立一個繼承自 Exception 類別的類
public class StudentNotFoundException extends Exception {

    public StudentNotFoundException (String message) {
        super(message);
    }
}
創建自己的異常時需要記住兩個規則:
  1. 我們的類別名稱必須以“Exception”結尾
  2. 類別必須包含一個帶有描述異常問題詳細資訊的字串變數的建構子。在建構函數中,呼叫超級建構函數並傳遞訊息。
使用產生的異常的範例:
public class StudentManager {
    public Student find(String studentID) throws StudentNotFoundException {
        if (studentID.equals("123456")) {
            return new Student();
        } else {
            throw new StudentNotFoundException(
                "Could not find student with ID " + studentID);
        }
    }
}
我們用程式碼捕捉這個異常:
public class StudentTest {
    public static void main(String[] args) {
        StudentManager manager = new StudentManager();
         try {
            Student student = manager.find("0000001");
        } catch (StudentNotFoundException ex) {
            System.err.print(ex);
        }
    }
}
執行程序的結果將是: StudentNotFoundException: Could not find Student with ID 0000001

為什麼需要寫異常?

1996 年,阿麗亞娜 5 號火箭因浮點變數到整型變數的錯誤轉換而墜毀。對於這種情況沒有例外或處理程序。如果在下載檔案時與 Internet 的連線遺失,則異常的存在將允許您在連線恢復後繼續下載。如果沒有異常,則必須重新開始下載。

參考:

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION