2011-04-20 83 views
0

我有一個抽象基類記錄,有說我要來當代碼是創建由派生類自動設置一個實例變量。因此,這裏的基類:Java的派生類不會自動生成實例

abstract public class CLog 
{ 
    /** Maintains the call stack level for each thread */ 
    private static HashMap<Integer, Integer> callStackLevel = new HashMap<Integer, Integer>(); 

    /** Static instance to be set by the derived class */ 
    private static CLog instance = null; 

    /** Logs in verbose */ 
    public static void v(String message) { if(instance != null) instance.verbose(getMessage(message)); } 
    /** Logs in debug */ 
    public static void d(String message) { if(instance != null) instance.debug(getMessage(message)); } 
    /** Logs in informational */ 
    public static void i(String message) { if(instance != null) instance.info(getMessage(message)); } 
    /** Logs in warning */ 
    public static void w(String message) { if(instance != null) instance.warn(getMessage(message)); } 
    /** Logs in error */ 
    public static void e(String message) { if(instance != null) instance.error(getMessage(message)); } 

    /** 
    * Calculates the message (with header) 
    */ 
    private static String getMessage(String message) 
    { 
     ... 
    } 

    /** Constructor sets instance */ 
    protected CLog() { instance = this; } 

    /** Logs in verbose */ 
    protected abstract void verbose(String message); 
    /** Logs in debug */ 
    protected abstract void debug(String message); 
    /** Logs in informational */ 
    protected abstract void info(String message); 
    /** Logs in warning */ 
    protected abstract void warn(String message); 
    /** Logs in error */ 
    protected abstract void error(String message); 
} 

我的一個Android記錄器創建派生類。我希望它能夠自動調用構造函數,但似乎這不起作用,因爲我的所有日​​志記錄函數都沒有產生任何結果。

public class AndroidLog extends CLog 
{ 
    protected static AndroidLog derived = new AndroidLog(); 

    @Override 
    protected void debug(String message) { 
     Log.d("Crystal", message); 
    } 

    @Override 
    protected void error(String message) { 
     Log.e("Crystal", message); 
    } 

    @Override 
    protected void info(String message) { 
     Log.i("Crystal", message); 
    } 

    @Override 
    protected void verbose(String message) { 
     Log.v("Crystal", message); 
    } 

    @Override 
    protected void warn(String message) { 
     Log.w("Crystal", message); 
    } 
} 

爲什麼這不起作用?當我在基類中調用靜態函數時,我沒有得到任何日誌。

反正只是通過編輯此AndroidLog類或通過在堵塞類,它是不依賴於AndroidLog,使這項工作做編輯?

+0

我不明白你想要做什麼。你是否在任何地方引用'AndroidLog'?如果不是,那麼它將不會被加載,因此構造函數從不會調用:類的純存在不會導致它被加載,它需要在某處引用。 – 2011-04-20 07:21:44

+0

在哪裏以及如何定義'Log'符號,併爲其創建對象? – 2011-04-20 07:23:32

+0

@Joachim所以即使我已經在派生類中聲明瞭一個靜態變量並將其設置爲等於該類的一個實例,但除非在類之外引用它,否則不會創建該變量? – 2011-04-20 07:26:52

回答

2

AndroidLog類的存在本身不會導致它自行啓動!

在Java類加載,如果使用它們初始化,而不是之前!所以除非你的某個類以某種相關方式引用AndroidLog,否則它永遠不會被加載,它是永遠不會被初始化的靜態字段,它的構造函數永遠不會被調用。

+0

@gamermb:您可以強制它加載,但:'C類=的Class.forName(「AndroidLog」);'這將告訴你需要它加載類,這將對其執行靜態初始化的JVM。但是,如果您從未參考它,我很難看到您如何調用它。我沒有看到構造函數中的任何代碼掛鉤到某些日誌框架或某些類似情況(這是您必須玩「Class.forName」遊戲的常見原因)。 – 2011-04-20 07:40:35

+0

基類構造函數設置實例變量。所以我需要的是一個派生類被實例化,因此調用基礎構造函數。 – 2011-04-20 15:56:07

+0

我對Class.forName()感到困惑。它是如何工作的,以及我在哪裏放置函數調用? – 2011-04-20 16:43:30

0

另一個重要的方面是,私有靜態類成員不繼承的事實!您的AndroidLog類將無法訪問基類中的任何私有靜態成員。

+0

我不在乎。總的來說,我希望我的所有類都使用基類靜態變量進行記錄,這些變量使用當前記錄器加載的實例。 – 2011-04-20 16:44:44