Walker
Walker

Reputation: 1225

Instantiating object using incompletely initialized 'this' as parameter

Assume I have a Warehouse class. That Warehouse has a TradeDesk. That TradeDesk computes available items to sell based on an instance variable set in Warehouse. A Warehouse's constructor instantiates a TradeDesk, but because TradeDesk needs an instance variable from the incompletely initialized Warehouse, we have a problem. Short of passing the instance value through multiple constructors (which I'd rather avoid; note that the below example is significantly simplified), how do I solve this? Thanks!

public class Warehouse {
    TradingDesk td;
    public int val;

    public Warehouse() {
        val = 3;
        td = new TradingDesk(this);
    }
// New class
public class TradingDesk {
    Warehouse associatedWh;
    int val;
    public TradingDesk(Warehouse wh) {
        associatedWh = wh;
        val = associatedWh.val;
    }
}

}

Upvotes: 1

Views: 97

Answers (3)

Edwin Dalorzo
Edwin Dalorzo

Reputation: 78619

Well, you could make of TradingDesk an inner class of WareHouse. This way it will have direct access to its enclosing WareHouse instance variables without the need of passing any parameters and it will be possible to create instances of it only within the context of a WareHouse instance.

public class Warehouse {

    private int val;
    private TradingDesk td;

    public Warehouse() {
        this.val = 3;
        this.td = new TradingDesk();
    }

    public class TradingDesk {

        public TradingDesk() {
            //this is the right way to access the enclosing instance
           if(WareHouse.this.val==3){
               //do something
           }
        }

        public WareHouse getAssociatedWareHouse(){
           return WareHouse.this;
        }
    }
}

Upvotes: 1

Mik378
Mik378

Reputation: 22191

Regarding your inner-class code, you attempt to initialize the Warehouse field with the instance of the outer class. So code becomes:

public class Warehouse {
    private TradingDesk td = new TradingDesk();
    private int val = 3;

    class TradingDesk {
         // you have already access to the outer Warehouse class including its fields
    }
}

Indeed, an inner-class have access to all properties of the outer class. So your issue disappears.

EDIT------------------

Here my solution to deal with the circular dependency:

public class Warehouse {
    private TradingDesk td = new TradingDesk();
    private int val = 3;

    public int getVal(){ //so accessible through TradingDesk object
        return val;
    }

    public void associateWhToTd(){
        td.setAssociatedWh(this); // no issue here since "this" is fully already created
    }

    public static void main(String[]args){ // example of usage
        Warehouse wh = new Warehouse();
        wh.associateWhToTd();
    }
}

public class TradingDesk {
    Warehouse associatedWh;

    public void setAssociatedWh(Warehouse wh){
       this.associatedWh = wh;
    }
}

Upvotes: 1

Jordão
Jordão

Reputation: 56487

You can use a lazily instantiated child object:

class Warehouse {
  private TradingDesk td;
  ...

  public Warehouse() {
    ...
  }

  public TradingDesk getTradingDesk() {
    if (td == null) td = new TradingDesk(this);
    return td;
  }
}

Just be aware that the above getter is not thread safe.

Don't escape this during construction.

Upvotes: 0

Related Questions