Reputation: 1225
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
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
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
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