finally关键字
用法:
和try catch 一起使用,它可以保证指定finally中的代码一定会执行,无论是否发生异常!
例如:
try{
}catch(){
}finally{
}
finally 块的主要作用:
资源释放:在 try 块中打开的资源(例如文件、数据库连接、网络连接等)可以在 finally 块中关闭或释放,以确保资源的正确释放,即使在发生异常的情况下也能够执行释放操作。
清理操作: finally 块可以用于执行一些清理操作,例如关闭打开的流、释放锁、取消注册监听器等。可能出现异常的代码
异常处理的补充: finally 块可以用于在 try 块和 catch 块之后执行一些必要的操作,例如记录日志、发送通知等。
当catch代码块中存在return语句时.
try{
//异常
}catch(Exception e){
int a=0;
return a;
}finally{
a=1;
System.out.println("已经执行finally语句块");
}
结果为:
已经执行finally语句块
返回值为0;
当try中存在错误时,会执行catch中的语句,会创建a并赋值为0,然后执行return 0,但是这不意味着方法立刻返回(即为方法结束,传出返回值),然后执行finally中的语句,即使finally中对a重新赋值,但对已经执行了的return并没有影响。然后方法结束,返回0;
如果不是int类型而是ArrayList这种引用类型会怎么样呢
public static void main(String[] args) {
System.out.println(testReturn2());
}
private static List<Integer>
testReturn2() {
List<Integer> list = new ArrayList<>
();
try {
list.add(1);
System.out.println("try:" +
list);
return list;
} finally {
list.add(3);
System.out.println("finally:" +
list);
}
}
结果为:
try:[1]
finally:[1, 3]
[1, 3]
为什么返回值是[1, 3]而不是[1],因为return的是list引用。这个引用指向堆中的ArrayList。
如果用引用类型String会怎么样呢:
public static void main(String[] args) {
System.out.println(testReturn3());
}
private static String testReturn3() {
String a = "hello";
try {
a += "!";
System.out.println("try:" + a);
return a;
} finally {
a += "world";
System.out.println("finally:" +
a);
}
}
结果:
try:hello!
finally:hello!world
hello!
虽然String是引用类型,但是String对象不可变。即使finally
块在try
块之后执行,并且a
在finally
块中再次被修改(再次创建一个新的String
对象并让a
指向它),但这并不会影响try
块中return
语句的行为。因为return
语句已经返回了a
当时指向的对象的引用(即"hello!"
),并且这个引用已经被复制到了调用栈中准备返回给main
方法。
String对象不可变:
这意味着一旦一个String
对象被创建,它的内容就不能被改变。当你尝试改变一个String
对象的内容时(比如通过+
运算符连接字符串),Java实际上是在内存中创建了一个新的String
对象,并将新对象的引用赋值给变量。原始的String
对象保持不变,
当catch,finally代码块中都存在return语句时.
int a=0;
try{
//异常
}catch(Exception e){
return a;
}finally{
a=1;
System.out.println("已经执行finally语句块");
return a;
}
当try中存在错误时,会执行catch中的语句,然后执行return 0,然后执行finally中的语句,a=1;输出”已经执行finally语句块“,然后执行return a,这里的return会覆盖catch中的return,输出a=1;