finally的一些特性

public class FinallyTest {
	public static void main(String[] args) {
		System.out.println("test1:" + testFinal1());
		System.out.println("test2:" + testFinal2());
		System.out.println("test3:" + testFinal3());
		System.out.println("test4:" + testFinal4());
	}

	static int testFinal1() {
		int i = 1;
		try {
			return i;
		} finally {
			System.out.println("in testFinal1():finally 肯定会被执行的!");
			i = 48;
		}
	}

	static String testFinal2() {
		String str = "try";  
		try {
			return str;  
		} finally {
			System.out.println("in testFinal2():finally 肯定会被执行的!");
			str = "finally";
		}
	}

	static StringBuilder testFinal3() {
		StringBuilder build = new StringBuilder("try ");
		try {
			return build;
		} finally {
			System.out.println("in testFinal3():finally 肯定会被执行的!");
			build.append("finally");
			build = new StringBuilder("你猜我是谁!");
		}
	}

	@SuppressWarnings("all")
	static String testFinal4() {
		try {
			return "return in try";
		} finally {
			System.out.println("in testFinal4():finally 肯定会被执行的!");
			return "return in finally";
		}
	}
}

 输出为:

in testFinal1():finally 肯定会被执行的!
test1:1
in testFinal2():finally 肯定会被执行的!
test2:try
in testFinal3():finally 肯定会被执行的!
test3:try finally
in testFinal4():finally 肯定会被执行的!
test4:return in finally

 * try finally特性:
   在try中的return语句会将返回结果值压栈,然后转入到finally子过程,等到finally子过程执行完毕之后

   (没有return),再返回。


   finally的语句是在方法return之前执行的,而且如果finally中有return语句的话,方法直接结束,不再

   返回栈中的值。

   java中方法调用都是采用传值模式,所以如果在finally中改变了引用类型的对象的值,则return返回后

   的结果也被改变。(实际上返回的是对象引用,并没有被改变,在finally中是直接对对象引用指向的

   对象进行了修改)

   在一个try-finally 语句中,finally 语句块总是在控制权离开try 语句块时执行的。
   当try 语句块和finally 语句块都意外结束时,在try 语句块中引发意外结束的原因将被丢弃,而整个try-finally

   语句意外结束的原因将于finally 语句块意外结束的原因相同。
   总之,每一个finally 语句块都应该正常结束,除非抛出的是不受检查的异常。
   千万不要用一个return、break、continue 或throw 来退出一个finally 语句块,并且千万不要允许将一个受

   检查的异常传播到一个finally 语句块之外去。
   如果一个catch 子句要捕获一个类型为E 的被检查异常,而其相对应的try 子句不能抛出E 的某种子类型的

   异常,那么这就是一个编译期错误。但是捕获Exception 或Throwble 的catch 子句是合法的,不管与其

   相对应的try 子句的内容为何。
   System.exit 将立即停止所有的程序线程,它并不会使finally 语句块得到调用,但是它在停止VM 之前会

   执行关闭挂钩操作。

//当你处理IO流,在finally 语句块中调用close 方法时,要用一个嵌套的try-catch语句来保护它,以防止IOException 的传播。
static void copy(String src, String dest) throws IOException {
	InputStream in = null;
	OutputStream out = null;
	try {
		in = new FileInputStream(src);
		out = new FileOutputStream(dest);
		byte[] buf = new byte[1024];
		int n;
		while ((n = in.read(buf)) > 0)
			out.write(buf, 0, n);
	} finally {
		//in可能抛出异常导致out无法关闭。
		//if (in != null) in.close();
		//if (out != null) out.close();
		closeIgnoringException(in);
		closeIgnoringException(out);
	}
}
private static void closeIgnoringException(Closeable c) {
	if (c != null) {
		try {
			c.close();
		} catch (IOException ex) {
			// There is nothing we can do if close fails
		}
	}
}

猜你喜欢

转载自jaesonchen.iteye.com/blog/2287615