Java:两个互相使用的对象

时间:2014-08-14 08:19:11

标签: java class object recursion

我无法解决的问题。我这里有简单的代码部分:

public class Item{
    Block blockDrop;

    public void setBlockDrop(Block block) {
        this.blockDrop = block;
    }
}

public class Block{
    Item itemDrop;

    public void setItemDrop(Item item) {
        this.itemDrop = item;
    }
}

public class ItemDirt extends Item {
    public ItemDirt() {
        setBlockDrop(Registry.blockDirt);
    }
}

public class BlockDirt extends Block {
    public BlockDirt() {
        setItemDrop(Registry.itemDirt);
    }
}

public class Registry {
    public static ItemDirt itemDirt = new ItemDirt();
    public static BlockDirt blockDirt = new BlockDirt();
}

当我运行它时,blockDirt会丢弃itemDirt,但是itemDirt WON' T drop blockDirt。有什么办法可以解决这个问题吗?我可以改为添加到Registry构造函数:

itemDirt.setBlockDrop(blockDirt);
blockDirt.setItemDrop(itemDirt);

但这会破坏我对象的整体简洁性。

3 个答案:

答案 0 :(得分:0)

问题在于,当构建ItemDirt并将其分配给Registry.itemDirt时,其构造函数已使用Registry.blockDirt,尽管它尚未初始化且仍为null时间点。

当物体试图在施工时过早地抓住外星物体时,会发生这种典型问题。通常情况下,构造函数永远不应该“到达”外部并抓住在那个时间点可能存在或不存在的其他对象。

答案 1 :(得分:0)

在没有对代码进行一些明显改动的情况下,似乎没有很好的方法可以打破你的恶性循环,但是这样的事情也可能不那么难看了:

public class Registry() {
    public static ItemDirt itemDirt;
    public static BlockDirt blockDirt;

    static {
        itemDirt = new ItemDirt();
        blockDirt = new BlockDirt();
        itemDirt.setBlockDrop(blockDirt);
    }
}

set方法中的一些延迟初始化。你的电话。

答案 2 :(得分:0)

看起来你正在尝试实现与Mediator Pattern类似的东西,但实际上这样做的方法不在构造函数中,因为你无法确定构造的顺序。

相反,当您实现业务方法时,您可以调用Mediator,然后Mediator处理类间通信。请在进一步了解之前阅读Mediator模式,因为它将提供一些有关如何更好地做到这一点的见解。