异常处理中,在捕获异常后还可以再次抛出异常,也可以在catch中return,那在finally中是否还可以再次抛出异常、是否可以return,下面是测试几种常用语言的结果总结
js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function test_except ( ) { try { let a = undefined a.b () } catch { console .log ('ex catched' ) } finally { console .log ('finally' ) throw 'error' return 1 } return 2 }
可以throw,可以return且throw、return后的语句都不可达
python 1 2 3 4 5 6 7 8 9 10 def test_except (): try : a = 1 /0 except : print ('ex catched' ) finally : return 1 return 2
同js
java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 private static int test_except () throws Exception { try { float a = 1 / 0 ; } catch (Exception e) { System.out.println("ex catched" ); } finally { System.out.println("finally" ); throw new Exception ("error" ); } }
行为和js一致,但是在throw或者return后的不可达代码被认为是语法错误
ruby 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #!/usr/bin/ruby -w def test_except begin a = 1 / 0 puts a rescue Exception => e puts e.message else puts 'else in except' ensure puts 'finally' raise 'error again' return 1 end return 2 end
ensure 等于 finally,行为和js一致。
c# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public int test_except (int num ) { int result = 0 ; try { result = 1 / num; } catch (DivideByZeroException e) { Console.WriteLine("except catched: {0}" , e); } finally { Console.WriteLine("Result: {0}" , result); throw new Exception("error" ); } return 2 ; }
finally中都可以再抛出异常,但不应当这么做,finally用于确保资源的正确释放。特别地:C# 不能从finally中return ,而其它几个语言finally块中的代码和其它地方代码没什么特别,只是在有、无异常都会被调用的语法糖。注意 :c++没有finally,在C++中通常使用RAII(Resource Aquisition Is Initialization).就是将资源封装成一个类,将资源的初始化封装在构造函数里,释放封装在析构函数里。通过局部变量析构函数总是会被调用的特性实现