java unreported exception_Java异常处理
大家好,歡迎來到樂字節(jié)小樂的Java技術分享園地
在計算機程序運行的過程中,總是會出現(xiàn)各種各樣的錯誤。
有一些錯誤是用戶造成的,比如,希望用戶輸入一個int類型的年齡,但是用戶的輸入是abc:
// 假設用戶輸入了abc:String s = "abc";
int n = Integer.parseInt(s); // NumberFormatException!
程序想要讀寫某個文件的內容,但是用戶已經(jīng)把它刪除了:
// 用戶刪除了該文件:String t = readFile("C:\\abc.txt"); // FileNotFoundException!
還有一些錯誤是隨機出現(xiàn),并且永遠不可能避免的。比如:網(wǎng)絡突然斷了,連接不到遠程服務器;
內存耗盡,程序崩潰了;
用戶點“打印”,但根本沒有打印機;
……
所以,一個健壯的程序必須處理各種各樣的錯誤。
所謂錯誤,就是程序調用某個函數(shù)的時候,如果失敗了,就表示出錯。
調用方如何獲知調用失敗的信息?有兩種方法:
方法一:約定返回錯誤碼。
例如,處理一個文件,如果返回0,表示成功,返回其他整數(shù),表示約定的錯誤碼:
int code = processFile("C:\\test.txt");
if (code == 0) {
// ok:} else {
// error: switch (code) {
case 1:
// file not found: case 2:
// no read permission: default:
// unknown error: }
}
因為使用int類型的錯誤碼,想要處理就非常麻煩。這種方式常見于底層C函數(shù)。
方法二:在語言層面上提供一個異常處理機制。
Java內置了一套異常處理機制,總是使用異常來表示錯誤。
異常是一種class,因此它本身帶有類型信息。異??梢栽谌魏蔚胤綊伋?#xff0c;但只需要在上層捕獲,這樣就和方法調用分離了:
try {
String s = processFile(“C:\\test.txt”);
// ok:} catch (FileNotFoundException e) {
// file not found:} catch (SecurityException e) {
// no read permission:} catch (IOException e) {
// io error:} catch (Exception e) {
// other error:}
因為Java的異常是class,它的繼承關系如下:
┌───────────┐
│ Object │
└───────────┘
▲
│
┌───────────┐
│ Throwable │
└───────────┘
▲
┌─────────┴─────────┐
│ │
┌───────────┐ ┌───────────┐
│ Error │ │ Exception │
└───────────┘ └───────────┘
▲ ▲
┌───────┘ ┌────┴──────────┐
│ │ │
┌─────────────────┐ ┌─────────────────┐┌───────────┐
│OutOfMemoryError │... │RuntimeException ││IOException│...
└─────────────────┘ └─────────────────┘└───────────┘
▲
┌───────────┴─────────────┐
│ │
┌─────────────────────┐ ┌─────────────────────────┐
│NullPointerException │ │IllegalArgumentException │...
└─────────────────────┘ └─────────────────────────┘
從繼承關系可知:Throwable是異常體系的根,它繼承自Object。Throwable有兩個體系:Error和Exception,Error表示嚴重的錯誤,程序對此一般無能為力,例如:OutOfMemoryError:內存耗盡
NoClassDefFoundError:無法加載某個Class
StackOverflowError:棧溢出
而Exception則是運行時的錯誤,它可以被捕獲并處理。
某些異常是應用程序邏輯處理的一部分,應該捕獲并處理。例如:NumberFormatException:數(shù)值類型的格式錯誤
FileNotFoundException:未找到文件
SocketException:讀取網(wǎng)絡失敗
還有一些異常是程序邏輯編寫不對造成的,應該修復程序本身。例如:NullPointerException:對某個null的對象調用方法或字段
IndexOutOfBoundsException:數(shù)組索引越界
Exception又分為兩大類:RuntimeException以及它的子類;
非RuntimeException(包括IOException、ReflectiveOperationException等等)
Java規(guī)定:必須捕獲的異常,包括Exception及其子類,但不包括RuntimeException及其子類,這種類型的異常稱為Checked Exception。
不需要捕獲的異常,包括Error及其子類,RuntimeException及其子類。
捕獲異常
捕獲異常使用try...catch語句,把可能發(fā)生異常的代碼放到try {...}中,然后使用catch捕獲對應的Exception及其子類:
// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
Run
如果我們不捕獲UnsupportedEncodingException,會出現(xiàn)編譯失敗的問題:
// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
Run
編譯器會報錯,錯誤信息類似:unreported exception UnsupportedEncodingException; must be caught or declared to be thrown,并且準確地指出需要捕獲的語句是return s.getBytes("GBK");。意思是說,像UnsupportedEncodingException這樣的Checked Exception,必須被捕獲。
這是因為String.getBytes(String)方法定義是:
public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {
...
}
在方法定義的時候,使用throws Xxx表示該方法可能拋出的異常類型。調用方在調用的時候,必須強制捕獲這些異常,否則編譯器會報錯。
在toGBK()方法中,因為調用了String.getBytes(String)方法,就必須捕獲UnsupportedEncodingException。我們也可以不捕獲它,而是在方法定義處用throws表示toGBK()方法可能會拋出UnsupportedEncodingException,就可以讓toGBK()方法通過編譯器檢查:
// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
Run
上述代碼仍然會得到編譯錯誤,但這一次,編譯器提示的不是調用return s.getBytes("GBK");的問題,而是byte[] bs = toGBK("中文");。因為在main()方法中,調用toGBK(),沒有捕獲它聲明的可能拋出的UnsupportedEncodingException。
修復方法是在main()方法中捕獲異常并處理:
// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
Run
可見,只要是方法聲明的Checked Exception,不在調用層捕獲,也必須在更高的調用層捕獲。所有未捕獲的異常,最終也必須在main()方法中捕獲,不會出現(xiàn)漏寫try的情況。這是由編譯器保證的。main()方法也是最后捕獲Exception的機會。
如果是測試代碼,上面的寫法就略顯麻煩。如果不想寫任何try代碼,可以直接把main()方法定義為throws Exception:
// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
Run
因為main()方法聲明了可能拋出Exception,也就聲明了可能拋出所有的Exception,因此在內部就無需捕獲了。代價就是一旦發(fā)生異常,程序會立刻退出。
還有一些童鞋喜歡在toGBK()內部“消化”異常:
static byte[] toGBK(String s) {
try {
return s.getBytes("GBK");
} catch (UnsupportedEncodingException e) {
// 什么也不干 }
return null;
這種捕獲后不處理的方式是非常不好的,即使真的什么也做不了,也要先把異常記錄下來:
static byte[] toGBK(String s) {
try {
return s.getBytes("GBK");
} catch (UnsupportedEncodingException e) {
// 先記下來再說: e.printStackTrace();
}
return null;
所有異常都可以調用printStackTrace()方法打印異常棧,這是一個簡單有用的快速打印異常的方法。
小結
Java使用異常來表示錯誤,并通過try ... catch捕獲異常;
Java的異常是class,并且從Throwable繼承;
Error是無需捕獲的嚴重錯誤,Exception是應該捕獲的可處理的錯誤;
RuntimeException無需強制捕獲,非RuntimeException(Checked Exception)需強制捕獲,或者用throws聲明;
不推薦捕獲了異常但不進行任何處理。
關注樂字節(jié),這里有更多更好的Java干貨知識
總結
以上是生活随笔為你收集整理的java unreported exception_Java异常处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 服务器基线加固脚本_Linux 基线检查
- 下一篇: centos 安装jdk_centos7