记录finnally的问题
参考链接: https://blog.csdn.net/Marmara01/article/details/85196803
final、finally、finalize 有什么区别?
- final:是修饰符,如果修饰类,此类不能被继承;如果修饰方法和变量,则表示此方法和此变量不能在被改变,只能使用。
- finally:是 try{} catch{} finally{} 最后一部分,finally 部分可以省略,但如果 finally 部分存在,则一定会执行 finally 里面的代码。
- finalize: 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法。
具体分析 finally
1.try-catch-finally 中哪个部分可以省略?
try-catch-finally 其中 catch 和 finally 都可以被省略,但是不能同时省略,也就是说有 try 的时候,必须后面跟一个 catch 或者 finally。
2.try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
情况一 finally 不会执行 在try之前发生异常 或 System.exit(0) 退出 (0正常退出,非0表示异常退出) finally代码不会执行
例子5 在try之前发生异常
/** * 运行结果 * Exception in thread "main" java.lang.ArithmeticException: / by zero * at com.test.TestFinally.Test5.testFinally(Test5.java:16) * at com.test.TestFinally.Test5.main(Test5.java:11) **/ public class Test5 { public static void main(String[] args) { testFinally(); } private static void testFinally() { int i = 5 / 0; try { System.out.println("try block"); } catch (Exception e) { System.out.println("catch block"); } finally { System.out.println("finally block"); } } }
例子6 System.exit(0) 退出
/**运行结果 * try block **/ public class Test6 { public static void main(String[] args) { testFinally(); } private static void testFinally() { try { System.out.println("try block"); System.exit(0); } catch (Exception e) { System.out.println("catch block"); } finally { System.out.println("finally block"); } } }
情况二 finally会执行
在try/catch/finally语句执行的时候,try块会首先执行,如果有异常发生,则进入catch块来匹配异常,
当匹配成功后则执行catch块中的代码,不管有无异常发生,都会执行finally块的代码(即时catch块中有return语句,finally块中的代码仍会执行);
当有异常发生后,catch和finally块进行处理后程序就结束了,就算finally块后面有代码也不会执行,如果没有异常发生时,在执行完finally块的代码后,后面的代码还会继续执行
例子1
/**运行结果 * 343423 */ public class Test1 { private static String result = ""; public static void main(String[] args) { f(0); f(-1); f(1); System.out.println(result); } public static void f(int i) { try { if (i == 1) { throw new Exception("exception message"); } } catch (Exception e) { result += "2"; return; } finally { result += "3"; } result += "4"; } }
在调用f(0)方法的时候,没有异常,因此,直接执行finally块和后面的代码块,方法的返回值为“34”;
在调用f(-1)方法的时候,没有异常,因此,直接执行finally块和后面的代码块,方法的返回值为“34”;
在调用f(1)方法的时候,产生异常,因此,只会执行catch块和finally块中的代码,方法返回值为“23”;
因此,这个程序的运行结果为343423。
例子2
/**运行结果 * execute finally * 1 */ public class Test2 { public static void main(String[] args) { int result = testFinally(); System.out.println(result); } private static int testFinally() { try { return 1; } catch (Exception e) { return 0; } finally { System.out.println("execute finally"); } } }
即使有 return 也要先执行 finally
例子3
/**运行结果 * execute finally * 3 **/ public class Test3 { public static void main(String[] args) { int result = testFinally(); System.out.println(result); } private static int testFinally() { try { return 1; } catch (Exception e) { return 0; } finally { System.out.println("execute finally"); return 3; } } }
当finally块中有return语句时,将会覆盖函数中其他return语句
例子4
/**
* 运行结果
* execute finally1
* 2
* execute finally2
* hello java World
**/
public class Test4 {
public static void main(String[] args) {
int resultVal = testFinally1();
System.out.println(resultVal);
StringBuffer buffer = testFinally2();
System.out.println(buffer);
}
private static int testFinally1() {
int result = 1;
try {
result = 2;
return result;
} catch (Exception e) {
return 0;
} finally {
result = 3;
System.out.println("execute finally1");
//return 666;
}
}
private static StringBuffer testFinally2() {
StringBuffer s = new StringBuffer("hello");
try {
s.append(" java");
return s;
} catch (Exception e) {
s.append(" python");
return null;
} finally {
s.append(" World");
System.out.println("execute finally2");
//return null;
//return new StringBuffer("abc");
}
}
}
finally中
有return 值会 覆盖其他rerurn值 无论 基本类型和引用类型
没有return 基本类型无法修改值 引用类型可以修改值