Java-異常-5種典型應用
目錄
文章目錄
內容
1、可能拋異常的靜態方法給靜態變量賦值
-
代碼
package exception.exception; public class TestException2 { public static void main(String[] args) { System.out.println(LuckNumber.a); } } // 幸運數字 class LuckNumber { static int a = getA(); // 此處報錯,未處理異常 //隨機0-9(排除2和4,4不吉利,2罵人) static int getA() throws Exception { int x = (int)Math.random(); if( x == 2 || x == 4) throw new Exception("數字不吉利"); return x; } }
-
問題:如上代碼所示,在static int a = getA()處又錯誤,未處理異常,怎麼辦呢?
- throws 只能用在方法簽名後
- try…catch 不能用在類體中
-
解決方案
把靜態變量聲明和賦值分離開,賦值操作在靜態代碼塊中完成,代碼如下所示:
package exception.exception;
public class TestException2 {
public static void main(String[] args) {
System.out.println(LuckNumber.a);
}
}
// 幸運數字
class LuckNumber {
static int a;
static {
try {
a = getA();
}catch (Exception e) {
e.printStackTrace();
}
}
//隨機0-9(排除2和4,4不吉利,2罵人)
static int getA() throws Exception {
int x = (int)(Math.random() * 10);
if( x == 2 || x == 4)
throw new Exception("數字不吉利");
return x;
}
}
- 測試結果:
-
正常
7
-
異常
java.lang.Exception: 數字不吉利 at exception.exception.LuckNumber.getA(TestException2.java:23) at exception.exception.LuckNumber.<clinit>(TestException2.java:14) at exception.exception.TestException2.main(TestException2.java:5) 0
-
2、繼承中的方法異常拋出問題
-
代碼
package exception.exception; public class TestException3 { public static void main(String[] args) { Father f = new Father(); Son s = new Son(); f.test(); s.test(); } } class Father { public void test() { System.out.println("父類test方法"); } } class Son extends Father { @Override public void test() throws ArithmeticException, NullPointerException{ System.out.println("子類test方法"); } }
-
問題:上述代碼能正常運行嗎?(不出異常)
- 之前學習繼承的時候,我們知道其中方法繼承,子類繼承自父類的方法,拋出的方法類型必須和父類相同或者是父類異常的子類
- 這樣想難道它不應該報錯嗎?
-
解析
事實上,自JDK7.0開始,所有方法簽名之後默認拋出RuntimeException運行時異常,不需要顯示指定。我們上面子類方法拋出的都是RuntimeException的子類,所以和我們之前學習並不違背。
3、finally中try…catch嵌套問題
-
現實需求:上小學的時候,我們喝熱水。統一都是水房內大鍋爐燒開,水房外一排水龍頭,憑水票打水。那麼冬天的時候呢,一般會提前把水管內涼水放一放。問題來了,現在水龍頭開着,需要關閉,但是因爲各種原因,某些水龍頭可能關不上了(比如,水龍頭滑絲了等等),出異常了,那麼我們應該試着關閉其他的水龍頭。
-
代碼
package exception.exception; public class TestException4 { public static void main(String[] args) { // 假設有3個水龍頭 Switch s1 = new Switch(); Switch s2 = new Switch(); Switch s3 = new Switch(); // 怎麼實現不管其中任意一個能不能關閉,都要嘗試去關閉其他水龍頭呢 } } // 開關類 class Switch { // 模擬關閉水龍頭 public void close() throws Exception{ int x = (int)(Math.random() * 10); if( x == 2 || x == 4) throw new Exception("水龍頭關不上了"); } }
-
解決方案
這裏我們就要用到finally代碼塊,並且嵌套try…catch,代碼如下:
package exception.exception;
public class TestException4 {
public static void main(String[] args) {
// 假設有3個水龍頭
Switch s1 = new Switch();
Switch s2 = new Switch();
Switch s3 = new Switch();
// 怎麼實現不管其中任意一個能不能關閉,都要嘗試去關閉其他水龍頭呢
try {
s1.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
s2.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
s3.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
// 開關類
class Switch {
// 模擬關閉水龍頭
public void close() throws Exception{
int x = (int)(Math.random() * 10);
if( x == 2 || x == 4)
throw new Exception("水龍頭關不上了");
System.out.println("水龍頭關上了");
}
}
- 測試結果
-
正常
水龍頭關上了 水龍頭關上了 水龍頭關上了
-
異常
java.lang.Exception: 水龍頭關不上了 at exception.exception.Switch.close(TestException4.java:37) at exception.exception.TestException4.main(TestException4.java:12) 水龍頭關上了 水龍頭關上了
-
4、變量需要在try…catch代碼塊和代碼塊之後使用問題
-
文件複製:把E:\a.txt複製爲F:\b.txt
-
代碼
package exception.exception; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class TestExeception6 { public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("e:\\a.txt"); FileOutputStream fos = new FileOutputStream("f:\\b.txt"); byte[] b = new byte[1024]; int len; while((len = fis.read(b)) != -1) { fos.write(b, 0, len); } } catch(Exception e) { e.printStackTrace(); } finally { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } System.out.println("文件複製完成!"); } }
-
問題:上面代碼在finally代碼塊中,fis,fos未聲明錯誤
-
解決
package exception.exception; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class TestExeception6 { public static void main(String[] args) { FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("e:\\a.txt"); fos = new FileOutputStream("f:\\b.txt"); byte[] b = new byte[1024]; int len; while((len = fis.read(b)) != -1) { fos.write(b, 0, len); } } catch(Exception e) { e.printStackTrace(); } finally { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } System.out.println("文件複製完成!"); } }
把聲明和賦值分離開,聲明部分放在try…catch 之前,擴大變量的作用域。
5、try…catch靈活運用
- 問題:判斷一個字符串中是否爲純數字
- 解決
-
傳統
public class TestException5 { public static void main(String[] args) { String str = "3222323x"; System.out.println(isDigit1(str)); } public static boolean isDigit1(String str) { char[] chars = str.toCharArray(); for(char x: chars) { if(!Character.isDigit(x)) return false; } return true; } }
測試結果:
“2342423" ---- > true "23232x" --------> false
-
try…catch
public class TestException5 { public static void main(String[] args) { String str = "3222323x"; System.out.println(isDigit2(str)); } public static boolean isDigit2(String str) { try { Integer.parseInt(str); return true; }catch(Exception e) { e.printStackTrace(); return false; } } }
-
後記 :
本項目爲參考某馬視頻開發,相關視頻及配套資料可自行度娘或者聯繫本人。上面爲自己編寫的開發文檔,持續更新。歡迎交流,本人QQ:806797785
前端項目源代碼地址:https://gitee.com/gaogzhen/vue-leyou
後端JAVA源代碼地址:https://gitee.com/gaogzhen/JAVA