2012-03-21 81 views
0

我正在實現我的Logger類,但由於一個奇怪的原因構造函數方法從未被調用過。在其他課上,當我使用SRCLogger.getLogger().log(Level.INFO, "Message");時,路徑上沒有創建日誌文件。構造函數在創建記錄器時未被調用java

我錯過了什麼?這段代碼有什麼問題?

這裏是我的代碼:

public final class SRCLogger implements Serializable{ 

    private static final Logger l = Logger.getLogger("mySRCLogger"); 
    private FileHandler fh; 

    private String ROOT_DIR = "C:\\Users\\Test\\Desktop\\"; 

    public SRCLogger(){ 
     System.out.println("Constructor."); 
     try { 
      fh = new FileHandler(ROOT_DIR + "SRCLog.log"); 
      fh.setFormatter(new SimpleFormatter()); 
      l.addHandler(fh); 
      System.out.println("Try."); 
     } catch (IOException ex) { 
      Logger.getLogger(SRCLogger.class.getName()).log(Level.SEVERE, null, ex); 
      System.out.println("Catch IOException."); 
     } catch (SecurityException ex) { 
      Logger.getLogger(SRCLogger.class.getName()).log(Level.SEVERE, null, ex); 
      System.out.println("Catch SecurityException."); 
     } 
    } 

    public static Logger getLogger(){ 
     return l; 
    } 
} 

歡呼和預先感謝

回答

4

很簡單 - 你永遠調用構造。你打電話的:

public static Logger getLogger(){ 
    return l; 
} 

...返回l,靜態字段這樣的初始化:

private static final Logger l = Logger.getLogger("mySRCLogger"); 

你爲什麼會認爲觸發你的類實例化?你沒有任何實例方法的事實也是一種設計氣味 - 除了向現有的記錄器添加處理程序外,你還期望類能夠完成什麼?如果這就是你想要做的,我會改變你的類,只是有一個靜態方法 - 你不需要任何實例,據我所知。

+0

所以,如果我想記錄器有處理程序,我應該把該處理程序的代碼放在靜態方法而不是構造函數? – BRabbit27 2012-03-21 17:38:22

+0

@ BRabbit27:你不是在寫一個*處理程序* - 你只是在創建一個'FileHandler'。將該處理程序添加到記錄器的代碼可以是靜態方法,是的。 – 2012-03-21 17:41:02

+0

你應該有一個靜態方法'private static init()',它應該包含你在構造函數中執行的所有任務。如果已經調用了'init',則可以保留一個布爾標誌。在'getLogger()'你應該檢查該標誌,如果它的'false'然後調用'init'否則不要 – 2012-03-21 17:49:55

0

爲了調用構造函數,必須使用「new」關鍵字實例化對象。如果僅調用類的靜態方法(而不是對象),則不會調用構造函數。

所以

SRCLogger.getLogger() 

是被稱爲靜態方法。

如果你這樣做

new SRCLogger().getLogger() 

,然後構造函數將被調用,但它不是好的做法呼籲的對象實例的靜態方法。靜態方法應該在類本身上調用。