使用未完全初始化的'this'作为参数实例化对象

时间:2012-10-31 01:19:47

标签: java

假设我有一个Warehouse类。该仓库有一个TradeDesk。 TradeDesk根据Warehouse中设置的实例变量计算要销售的可用项目。 Warehouse的构造函数实例化TradeDesk,但由于TradeDesk需要来自未完全初始化的Warehouse的实例变量,因此我们遇到了问题。没有通过多个构造函数传递实例值(我宁愿避免;注意下面的示例显着简化),我该如何解决?谢谢!

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

}

3 个答案:

答案 0 :(得分:1)

关于您的内部类代码,您尝试使用外部类的实例初始化Warehouse字段。 所以代码变成了:

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

实际上,内部类可以访问外部类的所有属性。 所以你的问题就消失了。

修改------------------

这里是我处理循环依赖的解决方案:

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

答案 1 :(得分:1)

好吧,你可以使TradingDesk成为WareHouse的内部类。通过这种方式,它可以直接访问其封闭的WareHouse实例变量,而无需传递任何参数,并且只能在WareHouse实例的上下文中创建它的实例。

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

答案 2 :(得分:0)

您可以使用延迟实例化的子对象:

class Warehouse {
  private TradingDesk td;
  ...

  public Warehouse() {
    ...
  }

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

请注意,上面的getter不是线程安全的。

Don't escape this during construction