1.try-catch-finally return 执行顺序
如try中没有异常,则顺序为try→finally;
如try中有异常,则顺序为try→catch→finally;
2.try-catch-finally return 执行顺序
当try、catch、finally中加入return之后,就会有几种不同的情况出现:
A、try中带return---》执行顺序为try→finally;return的是try中的值
先执行try并保存try中return的值,等finally执行完后,返回保存的return值
private static int tryCF(){
int a = 1;
try {
a++;
System.out.println("try:" + a);
return a;
} catch (Exception e) {
a++;
System.out.println("catch:" + a);
} finally {
a++;
System.out.println("finally:" + a);
}
return a;
}
//----------------结果-------------------
try:2
finally:3
方法的返回值:2
B、try中带return,finally中也带return---》执行顺序为try→finally;try中的return会失效,返回的是finally中的值,编译是可以编译通过的,但是编译器会给予警告,所以不推荐在finally中写return,这会破坏程序的完整性,而且一旦finally里出现异常,会导致catch中的异常被覆盖。
//不推荐在finally中写return
private static int tryCF(){
int a = 1;
try {
a++;
System.out.println("try:" + a);
return a;
} catch (Exception e) {
a++;
System.out.println("catch:" + a);
} finally {
a++;
System.out.println("finally:" + a);
return a;
}
}
//----------------结果-------------------
try:2
finally:3
方法的返回值:3
C、catch中带return---》执行顺序为try→catch→finally;return的catch中的值。
catch中return与try中一样,会先执行return前的代码,然后暂时保存需要return的值,再执行finally中的代码,最后再通过return返回之前保存的值。所以,这里方法返回的值是try、catch中累积计算后的3,而非finally中计算后的4。
private static int tryCF(){
int a = 1;
try {
a++;
System.out.println("try:" + a);
int x = a / 0 ;
} catch (Exception e) {
a++;
System.out.println("catch:" + a);
return a;
} finally {
a++;
System.out.println("finally:" + a);
}
return a;
}
//----------------结果-------------------
try:2
catch:3
finally:4
方法的返回值:3
D、try-catch-finally中都带return,//不推荐在finally中写return
结果和B一样,finally会覆盖了try or catch的保存的return值
// 不建议在finally中return
// 不建议在finally中return
private static int tryCF(){
int a = 1;
try {
a++;
System.out.println("try:" + a);
return a;
} catch (Exception e) {
a++;
System.out.println("catch:" + a);
return a;
} finally {
a++;
System.out.println("finally:" + a);
return a;
}
}
//----------------结果-------------------
try:2
finally:3
方法的返回值:3
private static int tryCF(){
int a = 1;
try {
a++;
System.out.println("try:" + a);
int x = a / 0;
return a;
} catch (Exception e) {
a++;
System.out.println("catch:" + a);
return a;
} finally {
a++;
System.out.println("finally:" + a);
return a;
}
}
//----------------结果-------------------
try:2
catch:3
finally:4
方法的返回值:4
3、finally中一旦发生异常,会把try,catch中的异常信息消化掉,程序中出现finally的报错,影响了try,catch的执行效果。
private static int tryCF(){
int a = 1;
try {
a++;
System.out.println("try:" + a);
return a;
} catch (Exception e) {
a++;
System.out.println("catch:" + a);
return a;
} finally {
a++;
System.out.println("finally:" + a);
int x = a / 0;
}
}
//--------------------------------
try:2
finally:3
Exception in thread "main" java.lang.ArithmeticException: / by zero
at TryCatchFinally.tryCF4(TryCatchFinally.java:33)
at TryCatchFinally.main(TryCatchFinally.java:16)
4、开发中常出现的问题:不推荐的写法
A、多个资源释放时,每个释放语句都要使用try保护,且不要将多个资源释放语句写在同一个try块内
// 多个资源释放时,每个释放语句都要使用try保护,且不要将多个资源释放语句写在同一个try块内
private static void testObj(String filePath){
File file = new File(filePath);
try {
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(oos);
oos.close();//多个资源释放
fos.close();//多个资源释放
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//----------推荐写法--------
//Java7及以上版本可以使用try-with-resources语句自动释放资源
//语法糖:简单易读
private static void testObjGood(String filePath){
File file = new File(filePath);
try (FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos))
{
oos.writeObject(oos);
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
B、问题一:finally中多个资源的释放,不能放在同一个try块内;
问题一:finally中的fos,oos有空指针的风险
private static void testObj2(String filePath) {
File file = new File(filePath);
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream(file);
oos = new ObjectOutputStream(fos);
oos.writeObject(oos);
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
oos.close();//多个资源的释放
fos.close();//多个资源的释放
} catch (IOException e){
e.printStackTrace();
}
}
}
//----------------推荐写法第二-------------------
//Java7及以上版本可以使用try-with-resources语句自动释放资源
//语法糖:简单易读
private static void testObjGood22(String filePath) {
File file = new File(filePath);
try (FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos))
{
oos.writeObject(oos);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//----------------推荐写法第一-------------------
private static void testObjGood2(String filePath) {
File file = new File(filePath);
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream(file);
oos = new ObjectOutputStream(fos);
oos.writeObject(oos);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (oos != null) {
try {
oos.close();//多个资源的释放
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();//多个资源的释放
} catch (IOException e) {
e.printStackTrace();
}
}
}
}