Java-異常-異常處理5種典型應用

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章