2011-01-19 9 views
1
Parent class(*ch.qos.logback.core.FileAppender*): 

    ... 

    protected String fileName = null; 

    public FileAppender() { 
     } 

      public void setFile(String file) { 
      if (file == null) { 
       fileName = file; 
      } else { 
       // Trim spaces from both ends. The users probably does not want 
       // trailing spaces in file names. 
       String val = file.trim(); 
       fileName = val; 
      } 
      } 
    ... 

子供クラス:のJava:子1で親クラスから変数を初期化して保持されていないヌル

... 
    public class FileAppender<E> extends ch.qos.logback.core.FileAppender<E> { 

    private FileResourceManager frm = new FileResourceManager(fileName, tempDir, false, loggerFacade); 


    public void writeOut(E event) throws IOException { 
     Object txId = null; 
     try { 
     frm.start(); 
     txId = frm.generatedUniqueTxId(); 
     frm.startTransaction(txId); 
     outputStream = frm.writeResource(txId, fileName, true); 
     outputStream.write(event.toString().getBytes()); 
     frm.commitTransaction(txId); 

     } 

     catch (Exception e) { 
    ... 
     } 
    } 

問題がfileNameがこの行のfrmにヌルとして渡されるということです。

private FileResourceManager frm = new FileResourceManager(fileName, tempDir, false, loggerFacade); 

frmインスタンスを作成するにはどうすればいいですか?nullなしfileName親ですでに初期化されていますか?

+2

'setFile'は質問に関連していませんが、どこからでも呼び出されるわけではありません。代わりに( 'new SomeClass(fileName)'で呼び出された)コンストラクタを文字列にするのがよいでしょう。 –

+3

問題を示す短くて完全なプログラムを提供してください。現時点でどのクラスを持っているのかははっきりしていません。 –

+0

@ジョン:私は投稿を編集して具体的なコードを挿入しましたが、そのアイデアは同じままです – sergionni

答えて

1

private static FileResourceManager frm; 
    public void writeOut(E event) throws IOException { 
     ... 

     if (frm == null) { 
      frm = new FileResourceManager(fileName, tempDir, false, loggerFacade); 
     } 

     Object txId = null; 
     try { 
... 
     } 

     catch (Exception e) { 
... 
} 
    } 

fileNameをWRITEOUT()メソッド内で(nullでない)初期化されます。 それほど上手くはありませんが、私の場合は最も簡単な解決策です。

0

親クラスでsetFile()メソッドを呼び出す必要があります。

0

がデフォルトコンストラクタを上書きし、あなたの「親クラス」は工assクラスであると仮定すると:

public Someclass(String fileName) { 
    this.fileName = fileName; 
} 
2

私が正しくあなたの質問を理解していれば、あなたは次のいずれかを行うことができます

  • 子クラスのコンストラクタでsetFile(file)を呼び出します。
  • 子のコンストラクタ(BTW、コード複製)のsetFile()メソッドにロジックを実装します。
  • 親クラスは、ファイルのパラメータを受け取るコンストラクタ、子クラス

UPDATE

AFAIUのコンストラクタでスーパー(ファイル)とコール親のコンストラクタを提供する場合、問題はフィールドの初期化順序です。子クラスのコンストラクタに「FRM」フィールドの初期化を移動する問題を解決する必要があります:

public FileAppender(String fileName) { 
    setFile(fileName); 
    frm = new FileResourceManager(fileName, tempDir, false, loggerFacade); 
    ... 
} 
+0

子クラスのsetFile()のロジックは同じでなければなりません - 重複をコードする必要はありません。私の子クラスが既にfileName paramを初期化していることが必要です。私の記事を編集したものを見て、私は実際のコードスニペットを挿入しました。 – sergionni

+0

親クラスにはno-param constructor(ch.qos.logback.core.FileAppender)のみがあります – sergionni

+0

コメントに従ってコメントが更新されました。 – Kel

2

あなたは親クラスのコンストラクタから呼び出しているオーバーライドsetFileですか?その場合:親クラスのコンストラクタは、子コンストラクタの有用な部分の前で実行されます。だからsetFileが親クラスのコンストラクタから呼び出され、その変数をnullにした子クラスのコンストラクタに制御が返されます。

インスタンスフィールドの初期化子とインスタンス初期化子は、実際には暗黙的にsuper(しかし、this()を呼び出していない)の呼び出しの後で、実際にはコンストラクタの一部です。私はCシャープは、スーパーへの呼び出しの前にインスタンスの初期設定を挿入すると信じています(しかし、彼らはthisを参照することはできません)。

対処:継承を避けることは常に良いことです。特に保護された変数を避け、コンストラクタからオーバーライド可能なメソッドを呼び出す。コンストラクターを単純なままにしてまた、= nullをインスタンスフィールドに追加しないでください。次のコードで解決さ

+0

setFile()は親クラスのメソッドで、fileName paramを初期化します。私のポストupdatedを参照してください。子クラスのインスタンスフィールドのために新しいときに私はすでに設定されたfileNameを子クラスに取得する必要があります。 – sergionni

+0

'setFile'はどこから呼び出されますか?新しいコードでは、派生クラスコンストラクターのフィールドをインスタンスフィールド初期化子を使用して使用しています。基本クラスのコンストラクタから呼び出さない限り、使用する前にフィールドを設定したようには見えません。 –