try執行,遇到異常就跳到catch
執行(以使得程序不會崩潰)
;
無論有沒有異常
catch,
最後都執行finally
若try塊中return 可達,
return語句(如:return x=x+1;):
- 對x執行運算x=x+1 (如有運算)
- 複製一個變量x給try的return語句(按值複製:基本類型就是值自己,對象就是地址值)
- 但return語句並不立刻返回,控制權轉移到finally塊中執行: (1)若finally中無return語句:finally執行完後,try塊執行return語句返回以前複製的變量x(基本類型就是值自己,對象就是地址值)(因此:若x爲基本類型,fianlly中改變x對最終return結果無效;若x爲對象類型,按地址值傳遞能夠改變x的最終return結果) (2)若finally中有return語句:執行後直接返回(即「覆蓋try中return語句」:try中return語句再也不返回)
若try中return 不可達(exception 在return前出現
):
exception出現後
控制權直接轉到
catch
塊(即
try中
exception以後的語句<包括return>不會執行
),最後到finally塊(catch到finally中流程與上面try
到finally中流程相同
)
- if you call System.exit() or
- if the JVM crashes first
- A return statement in the finally block is a bad idea:
By doing a return from the finally block, you suppress the exception entirely.
(
finally 中有return ,try,catch的 return throw都不會再被調用
)
publicstaticint getANumber(){
try{
thrownewNoSuchFieldException();
} finally {
return43;
}
}
Running the method above will
return a 「43」 and the exception in the try block will not be thrown. This is why it is considered to be a very bad idea to have a return statement inside the finally block.
例子解釋:
執行流程
- If the return in the try block is reached, it transfers control to the finally block, and the function eventually returns normally (not a throw).
- If an exception occurs, but then the code reaches a return from the catch block, control is transferred to the finally block and the function eventually returns normally (not a throw).
- In your example, you have a return in the finally, and so regardless of what happens, the function will return 34, because finally has the final (if you will) word.
finally語句在try或catch中的return語句執行以後、return返回以前執行的
publicclassFinallyTest1{
publicstaticvoid main(String[] args){
System.out.println(test1());
}
publicstaticint test1(){
int b =20;
try{
System.out.println("try block");
return b +=80;
}
catch(Exception e){
System.out.println("catch block");
}
finally {
System.out.println("finally block");
if(b >25){
System.out.println("b>25, b = "+ b);
}
}
return b;
}
}
運行結果:
try block
finally block
b>25, b =100
100
- 在catch中含有return+基本類型狀況(分析跟在try中含有return狀況同樣):
publicclassTest{
publicstaticvoid main(String[] args){
System.out.println(test1());
}
publicstaticint test1(){
int b =20;
try{
int a =1/0;//觸發異常
System.out.println("try block");//不會被執行
return b +=80;//不會被執行
}
catch(Exception e){
System.out.println("catch block");
return b +=180;//最後在此返回
}
finally {
System.out.println("finally block");
if(b >25){
System.out.println("b>25, b = "+ b);
}
}
// return b;
}
}
執行結果:
catch block
finally block
b>25, b =200
200
publicclassTest{
publicstaticvoid main(String[] args){
System.out.println(getMap().get("KEY").toString());
}
publicstaticMap<String,String> getMap(){
Map<String,String>map=newHashMap<String,String>();
map.put("KEY","INIT");
try{
map.put("KEY","TRY");
returnmap;//return在控制權轉移到finally前:複製了一個map對象的地址值(對象按地址值傳遞)
}
catch(Exception e){
map.put("KEY","CATCH");
}
finally {
map.put("KEY","FINALLY");//根據對象地址值修改對象內容(按地址值傳遞),所以會影響try中return返回的對象內容
map= null;//map爲null即再也不指向該對象,
// 但因爲前面return複製了一個對象的引用(地址值),而對象是被分配在堆中的,只要有引用指向這個對象,系統就不會回收此對象,
因此此處map = null 並不會影響最後try中return返回對象內容
}
returnmap;
}
}
執行結果:
- 在catch中含有return+基本類型狀況(分析跟在try中含有return狀況同樣):
publicclassTest{
publicstaticvoid main(String[] args){
System.out.println(getMap().get("KEY").toString());
}
publicstaticMap<String,String> getMap(){
Map<String,String>map=newHashMap<String,String>();
map.put("KEY","INIT");
try{
int a =1/0;//觸發異常
map.put("KEY","TRY");//不會被執行
returnmap;//不會被執行
}
catch(Exception e){
map.put("KEY","CATCH");
returnmap;//return在控制權轉移到finally前:複製了一個map對象的地址值(對象按地址值傳遞)
}
finally {
map.put("KEY","FINALLY");//根據對象地址值修改對象內容(按地址值傳遞),所以會影響catch中return返回的對象內容
map= null;//map爲null即再也不指向該對象,
// 但因爲前面return複製了一個對象的引用(地址值),而對象是被分配在堆中的,只要有引用指向這個對象,系統就不會回收此對象,
// 因此此處map = null 並不會影響最後catch中return返回對象內容
}
// return map;
}
}
執行結果:
finally塊中的return語句會覆蓋try塊中的return返回
publicclassTest{
publicstaticvoid main(String[] args){
System.out.println(test2());
}
publicstaticint test2(){
int b =20;
try{
System.out.println("try block");
return b +=80;
}catch(Exception e){
System.out.println("catch block");
} finally {
System.out.println("finally block");
if(b >25){
System.out.println("b>25, b = "+ b);
}
return200;
}
// return b;
}
}
執行結果:
try block
finally block
b>25, b =100
200