2011-04-20 5 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); 
} 

나는 안드로이드 로거 용 파생 클래스를 만듭니다. 나는 그것이 생성자를 자동으로 호출하기를 원하지만 모든 로깅 함수로 인해 아무것도 발생하지 않기 때문에 이것이 작동하지 않는 것 같습니다.

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에 종속되지 않는 CLog 클래스를 편집하여이 작업을 수행 할 수 있습니까?

+0

나는 당신이하려는 것을 정확히 이해하지 못합니다. 어디서나'AndroidLog'를 참조하십니까? 그렇지 않으면 클래스가로드되지 않고 생성자가 호출되지 않습니다. 클래스의 순수한 존재는 **로드되지 않기 때문에 어딘가에서 참조해야합니다. –

+0

'Log' 심볼은 어디에 정의되어 있으며, 어떻게 그것에 할당 된 객체가 생성됩니까? –

+0

@Joachim 따라서 파생 클래스에서 정적 변수를 선언하고 클래스의 인스턴스와 같게 설정하더라도 클래스 외부에서 참조되지 않으면 클래스가 만들어지지 않습니다. –

답변

2

단지 AndroidLog 클래스의 존재로 인해 부트 스트랩 자체가 발생하지 않습니다!

Java 클래스는 이전에는 사용되지 않았을 때로드되고 초기화되었습니다. 따라서 어딘가 어떤 클래스가 어떤 관련 방법으로 AndroidLog을 참조하지 않으면로드되지 않습니다. 정적 필드는 초기화되지 않고 해당 생성자는 절대 호출되지 않습니다.

+0

@gamermb : 강제로로드 할 수 있습니다 :'Class c = Class.forName ("AndroidLog");'그러면 JVM에 클래스를로드하는 데 필요한 정적 정적 초기화가 수행됩니다. 그러나 당신이 그것을 결코 참조하지 않는다면 당신이 그것을 부르고있는 것을 보는 것을 보는 데 어려움을 겪고 있습니다. 생성자에서 일부 로깅 프레임 워크 또는 일부 등의 코드를 보지 못합니다 (이는 'Class.forName' 게임을 수행해야하는 일반적인 이유입니다). –

+0

기본 클래스 생성자가 인스턴스 변수를 설정합니다. 그래서 필자가 필요로하는 것은 파생 클래스를 인스턴스화하여 기본 생성자를 호출하는 것입니다. –

+0

Class.forName()에 대해 혼란스러워합니다. 어떻게 작동하고, 정확히 어디에서 함수 호출을할까요? –

0

또 다른 중요한 측면은 개인 정적 클래스 멤버가 상속되지 않는다는 사실입니다. AndroidLog 클래스는 기본 클래스에있는 비공개 정적 멤버에 액세스 할 수 없습니다.

+0

상관 없어요. 요점은 모든 클래스가 현재의 로거가로드 된 인스턴스를 사용하는 기본 클래스 정적 변수를 사용하여 로그하도록하려는 것입니다. –

관련 문제