try-catch思考

紅豆生南國,春來發幾枝。願君多采擷,此物最相思。

(原創不容易,引用請標記,謝謝)


try catch爲一般用於java中的異常處理,

1:try()的用法:

try()是1.7新增的用法,用來自動關閉括號內能關閉的資源,而不必要手動關閉,其必須實現autocloseable接口,

such as下列代碼,MySource是資源類,繼承了AutoCloseable接口

public class Myresource implements AutoCloseable{

	@Override
	public void close() throws Exception {
		System.out.println("正在執行關閉方法");
	}
	public void throwTest(int k) throws Exception{
		System.out.println("正在執行方法throwTest");
		if(k>5){
			throw new Exception();
		}
	}
}

而我測試類這樣寫時:

public class TryTest {
	public static void main(String[] args) {
		 try{
		 Myresource myresource = new Myresource();
		 myresource.throwTest(4);
		 }catch (Exception e) {
		 e.printStackTrace();
		 }
	}
}

執行結果爲:

並不會自動關閉類

但是當我測試類這樣寫時:

public static void main(String[] args) {
		try (Myresource myresource = new Myresource()) {
			myresource.throwTest(4);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

運行結果爲:


將自動關閉資源,測試了下上面資源類繼承closeable接口時,採用下面的方法,運行結果也會自動關閉資源,

2:try的返回值問題

當try catch  final  中都有return的時候怎麼返回呢,寫demo

public class TryTest {
	public static void main(String[] args) {
		System.out.println(getRet());
	}
	public static String getRet(){
		String string = "";
		try{
			string = "try model";
			System.out.println("try 執行");
			return string;
		} catch (Exception e) {
			string = "catch model";
			System.out.println("catch 執行");
			return string;
		}finally {
			string = "finally model";
			System.out.println("finally 執行");
		}
	}
}

執行結果爲:


預料中執行finally已經把值改變爲finally 了  但是返回的確實try

javap -verbose一下:

 

    Code:
      stack=2, locals=4, args_size=0
         0: ldc           #34                 // String
         2: astore_0
         3: ldc           #36                 // String try model
         5: astore_0
         6: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
         9: ldc           #38                 // String try 執行
        11: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        14: aload_0
        15: astore_3
        16: ldc           #40                 // String finally model
        18: astore_0
        19: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
        22: ldc           #42                 // String finally 執行
        24: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        27: aload_3
        28: areturn
        29: astore_1
        30: ldc           #44                 // String catch model
        32: astore_0
        33: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
        36: ldc           #46                 // String catch 執行
        38: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        41: aload_0
        42: astore_3
        43: ldc           #40                 // String finally model
        45: astore_0
        46: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
        49: ldc           #42                 // String finally 執行
        51: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        54: aload_3
        55: areturn
        56: astore_2
        57: ldc           #40                 // String finally model
        59: astore_0
        60: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
        63: ldc           #42                 // String finally 執行
        65: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        68: aload_2
        69: athrow

第0-2給string0賦值“”,並儲存
第3-5 給string0賦值“try model“,並儲存
第6-11  調用靜態方法print並打印“try 執行”
第14-15  把string0的值放進另一個string3
第16-18 給string0賦值“finally model”
第19-24 打印“String finally 執行”

第27-28 加載string3(當前是以前的string0即“try model”),然後返回

由此可知,實際返回的是try model,在執行try之前會有一個臨時變量String3將string0裝進去,然後返回。

當在finally中返回的時候呢?代碼如下:

public class TryTest2 {
	public static void main(String[] args) {
		System.out.println(getRet());
	}
	public static String getRet(){
		String string = "";
		try{
			string = "try model";
			System.out.println("try 執行");
			return string;
		} catch (Exception e) {
			string = "catch model";
			System.out.println("catch 執行");
			return string;
		}finally {
			string = "finally model";
			System.out.println("finally 執行");
			return string;
		}
	}
}

得到的結果爲:


同理分析javap  皮一下

Code:
      stack=2, locals=2, args_size=0
         0: ldc           #34                 // String
         2: astore_0
         3: ldc           #36                 // String try model
         5: astore_0
         6: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
         9: ldc           #38                 // String try 執行
        11: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        14: goto          33
        17: astore_1
        18: ldc           #40                 // String catch model
        20: astore_0
        21: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
        24: ldc           #42                 // String catch 執行
        26: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        29: goto          33
        32: pop
        33: ldc           #44                 // String finally model
        35: astore_0
        36: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
        39: ldc           #46                 // String finally 執行
        41: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        44: aload_0
        45: areturn

同上面的分析,不同的是14行的時候就goto到33,33-35直接把“finally model”裝進string0

然後打印“finally 執行” 最後aload加載string0  然後返回,即返回的是“finally model”

萬一遇見個錯誤呢怎麼返回,代碼一下:

public class TryTest2 {
	public static void main(String[] args) {
		System.out.println(getRet());
	}
	public static String getRet(){
		String string = "";
		try{
			string = "try model";
			System.out.println("try 執行");
			int k = 5/0;
			return string;
		} catch (Exception e) {
			string = "catch model";
			System.out.println("catch 執行");
			return string;
		}finally {
			string = "finally model";
			System.out.println("finally 執行");
		}
	}
}

返回的結果爲:


皮一下:

Code:
      stack=2, locals=4, args_size=0
         0: ldc           #34                 // String
         2: astore_0
         3: ldc           #36                 // String try model
         5: astore_0
         6: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
         9: ldc           #38                 // String try 執行
        11: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        14: iconst_5
        15: iconst_0
        16: idiv
        17: istore_1
        18: aload_0
        19: astore_3
        20: ldc           #40                 // String finally model
        22: astore_0
        23: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
        26: ldc           #42                 // String finally 執行
        28: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        31: aload_3
        32: areturn
        33: astore_1
        34: ldc           #44                 // String catch model
        36: astore_0
        37: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
        40: ldc           #46                 // String catch 執行
        42: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        45: aload_0
        46: astore_3
        47: ldc           #40                 // String finally model
        49: astore_0
        50: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
        53: ldc           #42                 // String finally 執行
        55: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        58: aload_3
        59: areturn
        60: astore_2
        61: ldc           #40                 // String finally model
        63: astore_0
        64: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
        67: ldc           #42                 // String finally 執行
        69: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        72: aload_2
        73: athrow

分析分析,前面講過的不說,第14-16行除法,存進寄存器1中,遇見異常還是直接跳過第一個return還是咋的

跳過第一個return不說(具體原因我也不清楚),34-46  將string0標記爲“catch model”然後打印“catch 執行”然後裝進寄存器3中,其他同上面1的裏,然後的還是寄存器3裏面的值。

在異常的時候  finally加return  

public class TryTest2 {
	public static void main(String[] args) {
		System.out.println(getRet());
	}
	public static String getRet(){
		String string = "";
		try{
			string = "try model";
			System.out.println("try 執行");
			int k = 5/0;
			return string;
		} catch (Exception e) {
			string = "catch model";
			System.out.println("catch 執行");
			return string;
		}finally {
			string = "finally model";
			System.out.println("finally 執行");
			return string;
		}
	}
}

這個就不說了 和第二個類似  返回finally model

在catch裏面遇見異常呢:

public class TryTest2 {
	public static void main(String[] args) {
		System.out.println(getRet());
	}
	public static String getRet(){
		String string = "";
		try{
			string = "try model";
			System.out.println("try 執行");
			int k = 5/0;
			return string;
		} catch (Exception e) {
			string = "catch model";
			System.out.println("catch 執行");
			int k = 5/0;
			return string;
		}finally {
			string = "finally model";
			System.out.println("finally 執行");
		}
	}
}

直接返回異常

在finally的時候返回呢?

public class TryTest2 {
	public static void main(String[] args) {
		System.out.println(getRet());
	}
	public static String getRet(){
		String string = "";
		try{
			string = "try model";
			System.out.println("try 執行");
			int k = 5/0;
			return string;
		} catch (Exception e) {
			string = "catch model";
			System.out.println("catch 執行");
			int k = 5/0;
			return string;
		}finally {
			string = "finally model";
			System.out.println("finally 執行");
			return string;
		}
	}
}

運行結果:


總結總結:在finally中返回,必爲返回值finally

如果在catch中抓取的不是那個異常,或者catch中遇見異常,或者finally中遇見異常直接拋出異常

try中異常 返回的是try中的值

so:千萬不要在finally中return




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