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




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