Question

I want to wrap a class in Java but the problem is as follows:

public class A {

    public A() {
       doSomething();
    }

    public void doSomething() {
    }

}

Now when I try to wrap this class and delegate all methods to the wrapper

public class Wrapper extends A {

   private final A a;

   public Wrapper(A a) {
      super();
      this.a = a;
   }

   @Override
   public void doSomething() {
      this.a.doSomeThing();
   }


}

of course I get a NPE as 'a' is still null as it is set after the super()-call which calls the overriden doSomething() method. Is there any solution for this problem? The only thing that came to my mind was making a factory method and setting a static variable holding the reference to a but this seems ugly to me.

Was it helpful?

Solution 3

A way for this to be avoided is by exposing an init method (or any other name) from your base class (if you are in control of its logic). Then move the call from the constructor to the init method:

public class A {

    public A() {
    }

    public void init() {
        doSomething();
    }

    public void doSomething() {
    }
}

You should update your code to call the init method after making an instance of the class, which may be a bit of boilerplate:

A instance = new Wrapper();
instance.init();

instead of just

A instance = new Wrapper();

If you use Spring and DI, you can specify an init-method in the xml context, so Spring will call it for you when it resolves the dependency.

In case the doSomething method is public, and accepts no arguments, you can use it directly instead of the init method both in code and with Spring.

In general, use of overridable methods in a constructor is an anti-pattern, due to the problem you have encountered. There is no way to predict how a derived class will override the methods and if they rely on non-initialized resources, then you are in trouble.

OTHER TIPS

I'd recommend changing the code so that doSomething is not called in the constructor.

Alternatively split A into an interface and implementation Wrapper implements the interface and does not inherit from A

public interface IA {

    public void doSomething() {
    }

}
public class A implements IA {

    public A() {
       doSomething();
    }

    public void doSomething() {
    }

}


public class Wrapper implements IA {

   private final IA a;

   public Wrapper(IA a) {
      this.a = a;
      doSomething();
   }

   @Override
   public void doSomething() {
      a.doSomeThing();
   }
}

Change your Wrapper this way. You do not need to hold A explicitly. The expression super is the same as your filed:

class Wrapper extends A {

    public Wrapper() {
    }

    @Override public void doSomething() {
        super.doSomething();
    }
}

Or otherwise extract an interface and change your code like this:

class Wrapper implements AA {

    private final AA child;

    public Wrapper(AA child) {
        this.child = child;
    }

    @Override public void doSomething() {
        child.doSomething();
    }
}

class A implements AA {

    public A() {
       doSomething();
    }

    @Override public void doSomething() {}
}

interface AA {
    public void doSomething();
}

two small changes, young one you need

 public class Wrapper extends A {

       private final A a;

       public Wrapper(A a) {
          super();
          this.a = a;

        //this will execute method doSomething wrom Wrapper class after variable a is set
          doSomething(); 

       }

       @Override
       public void doSomething() {
    //this will prevent to call metod from superclass constructor, bit risky thou
         if (a!=null)       
          this.a.doSomething();
       }
    }

but overriding methods which are called in constructo is generally bad practice and smells terrible

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top