java的try-catch-fianlly的陷阱

java的try-catch-fianlly的陷阱

2019-11-28 22:04:07

在学习java的异常的时候,总是有:如果遇见try-catch-finally 块,不管try,catch的情况如何,finally块总是会执行。但是对于下面几种或情况比较特殊:


1.当在try中遇到return语句

public class TryCatch {
	public TryCatch(){
		try {
			
			System.out.println("try中的return之前");
			return ;
		//	System.out.println("try中的return之前");   //提示此行为不可达
			
			
		}catch (Exception e) {
			// TODO: handle exception
		}finally {
			System.out.println("执行finally");
		}
	}
	public static void main(String[] args) {
		new TryCatch();
	}
}

输出结果:
try中的return之前
执行finally
可以看出:当try中遇到return语句,finally块还是会执行。执行完之后,立即返回。

2.return 语句后面的代码要执行吗 ?(比如return a++语句后面的 a++要执行吗?)

public class TryCatch {
	private int i=5;
	public int test() {
		try {
			
			System.out.println("try中的return之前"+'\n'+"i值是:"+i);
			return ++i;
		//	System.out.println("try中的return之前");   //提示此行为不可达
			
			
		}catch (Exception e) {
			// TODO: handle exception
		}finally {
			System.out.println("执行finally"+"   i的值是:"+i);
	//	   return i+10;                                               // ①
		}
		return i+5;
	}
	public static void main(String[] args) {
		System.out.println(new TryCatch().test());
	}
}

输出结果:
try中的return之前
i值是:5
执行finally i的值是:6
6

如果finally块中,①处不加注释结果就是:
try中的return之前
i值是:5
执行finally i的值是:6
16


可以看出,当try块中遇到return后,会执行return后的语句,执行完之后就会到finally块中继续执行,当fianlly块中,有return语句,则会在finally块的return处结束。否则返回到try块处结束

3.try块中遇到System.exit(0)呢?

public class TryCatch {
	private int i=5;
	public int test() {
		try {
			
			System.out.println("try中的return之前"+'\n'+"i值是:"+i);
			System.exit(0);
			
			
		}catch (Exception e) {
			// TODO: handle exception
		}finally {
			System.out.println("执行finally"+"   i的值是:"+i);
	//	   return i+10;
		}
		return i+5;
	}
	public static void main(String[] args) {
		System.out.println(new TryCatch().test());
		System.out.print("最后一行");
		
	}
}

输出结果:
try中的return之前
i值是:5
结果并没有执行: System.out.print(“最后一行”); 因为System.exit(0)会停止当前线程,和所有其他线程当成死亡,
System.exit(0)被调用时,虚拟机退出前要执行:
1、执行系统中注册的所有关闭钩子。
2、如果程序调用了System.runFinalizerOnExit(true);,那么JVM会对所有的还未结束的对象调用Finalizer。

第二种方式已经被证明是极度危险的,因此JDK API文档中说明第二种方式已经过时了,因此实际开发中不应该使用这种危险的行为。

可以看下面的System.out.在API中的声明:

public static void exit​(int status)
Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination.
This method calls the exit method in class Runtime. This method never returns normally.

The call System.exit(n) is effectively equivalent to the call:

 Runtime.getRuntime().exit(n)
 
Parameters:
status - exit status.
Throws:
SecurityException - if a security manager exists and its checkExit method doesn't allow exit with the specified status.
See Also:
Runtime.exit(int)

4.如果try中遇到throw语句呢?

public class TryCatch {
	public void test() {
		try {
			throw new RuntimeException("try处异常");	
		}finally {
			System.out.println("执行finally");
			return ;            					 //  ①
		}
	}
	public static void main(String[] args) {
		new TryCatch().test();
	}
}

输出结果:执行finally
如果注释掉 ① 结果时L:
Exception in thread “main” java.lang.RuntimeException: try处异常
执行finally
at lianxi.TryCatch.test(TryCatch.java:6)
at lianxi.TryCatch.main(TryCatch.java:13)

当这个符合了finally的执行流程,当程序执行try,catch块时,如果遇到throw语句,throw语句会导致该方法立即结束,系统在执行throw语句时并不会立即抛出异常,而是去寻找是否包含finally块,如果没有,则会立即抛出异常,如果有finally块,会将finally块执行完成后,系统才会再次跳回来抛出异常,如果finally块中有return语句,会在return处结束,也不会抛出异常。

你可能感兴趣的:(java基础编程)