2013-09-10 55 views
0

我期待以下代碼在設置靜態變量值的語句之前打印行,但它不按預期工作。java字節碼是不是按順序執行?

import java.io.PrintWriter; 
class Bank{ 
private static boolean isInCrisis = false; 
public static boolean getIsInCrisis(){return Bank.isInCrisis;} 
public static boolean setIsInCrisis(boolean crisis){ 
    return Bank.isInCrisis = crisis; 
} 
public String getCash() throws Exception{ 
    if(!Bank.isInCrisis){ 
     return new String("$100"); 
    } 
    else{ 
     throw new Exception("Bank is in crisis"); 
    } 
} 
} 

public class InstanceObjects{ 
public static void main(String... st) { 
    try{ 
     Bank hsbc = new Bank(); 
     PrintWriter writer = new PrintWriter(System.out); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     hsbc.setIsInCrisis(true); 
     writer.printf("collect cash: %s\n",hsbc.getCash());    
     writer.close(); 
    }catch(Exception e){ 
     e.printStackTrace(); 
    } 
} 
} 

輸出拋出異常「銀行危機」,但它應該首先打印的「收取現金......」消息的一些線條,然後扔異常信息...

+0

請包括整個堆棧跟蹤,並指示在聲明中'主()'在異常被拋出(應該是第二個'at'線)。 –

+0

@mabbas,以及'hsbc.setIsInCrisis(true)'上面的printf語句呢?輸出應該是:收集現金$ 100,....,例外被捕獲....銀行處於危機...... –

+0

java.lang.Exception:銀行處於危機 \t at Bank.getCash(InstanceObjects.java: 13) \t at InstanceObjects.main(InstanceObjects.java:31) –

回答

5

問題是你的PrintWriter永遠不會被刷新。它正在積累數據,但它從不將它寫入控制檯,因爲在緩衝區滿之前拋出異常。

如果在引發異常的調用之前調用writer.flush(),您將看到預期的消息。

如果關閉了作家在finally塊,你會看到數據時,它的關閉,因爲這也刷新作家......但異常後,爲catchfinally之前執行。

如果使用try-with-resources塊代替,你會看到數據異常之前,因爲那裏的close發生在「嵌套」嘗試/終於,有效:

try (PrintWriter writer = new PrintWriter(System.out)) { 
    Bank hsbc = new Bank(); 
    ... 
} catch(Exception e){ 
    // writer will already be closed here 
    e.printStackTrace(); 
} 
+0

明白了!謝謝, –

0

你忘了

writer.flush();

printf方法不會自動刷新,郵件將被坐在一個緩衝區,它永遠不會被髮送到安慰。

0

嘗試在獲取引發異常的消息之前刷新流。

public class Main{ public static void main(String... st) { 
    try{ 
     Bank hsbc = new Bank(); 
     PrintWriter writer = new PrintWriter(System.out); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     writer.printf("collect cash: %s\n",hsbc.getCash()); 
     writer.flush(); 
     hsbc.setIsInCrisis(true); 
     writer.printf("collect cash: %s\n",hsbc.getCash());    
     writer.close(); 
    }catch(Exception e){ 
     e.printStackTrace(); 
    } } } 

打印:

collect cash: $100 
collect cash: $100 
collect cash: $100 
collect cash: $100 
collect cash: $100 
collect cash: $100 
collect cash: $100 
java.lang.Exception: Bank is in crisis 
    at Bank.getCash(Main.java:13) 
    at Main.main(Main.java:32)