开发者

Java: variable from parent class in child one isn't initialized and holds null

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;
            }
          }
    ...

Child class:

    ...
   public class FileAppe开发者_运维知识库nder<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) {
    ...
      }
     }

The problem is that fileName is passed as null to frm in this line:

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

How can i create frm instance,with not-null fileName,e.g. already initialized in parent?


If I understand your question correctly, you can do one of the following:

  • call setFile(file) in constructor of child class
  • implement logics placed in setFile() method in child's constructor (BTW, that'll be code duplication)
  • if parent class provides constructor, which accepts file parameter, call parent's constructor with super(file) in constructor of child class

UPDATE

AFAIU, the problem is in fields initialization order. The moving "frm" field initialization into child class constructor should solve the problem:

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


Is setFile an override that you are calling from the parent class constructor? In that case: The parent class constructor runs before the useful part fo the child constructor. So setFile is called from the parent class constructor, and then control is returned to the child class constructor which you have nulling out that variable.

The instance field initialisers and instance initialisers are actually part of constructors, after the possibly implicit call to super (but not if they call this()). I believe C sharp inserts instance initialisers before the call to super (but they can't reference this).

What to do: Avoiding inheritance is always good. In particular avoid protected variables and calling overridable methods from constructors. Keep constructors simple. And don't add = null to instance fields.


Resolved with following code:

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 is initialized(not null) within writeOut() method. Not very gracefully,but looks like simplest solution in my case.


You have to call the setFile() method in the parent class.


Assuming that your "parent class" is the SomeClass class, overwrite the default constructor there:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜