Java一步传递两个object

Java pass two object to each others in one step

我有以下主要 class 和主要方法:

public class Main {

Peter peter = new Peter(this);
Tom tom = new Tom(this);

    public static void main(String[] args) {
        Main main = new Main();
        System.out.println(main.peter.tom);
        System.out.println(main.tom.peter);
    }
}

和以下 Parent class:

class Enemy {
     //some variables
}

和以下两个 child classes:

class Tom extends Enemy {

    Enemy peter;

    Tom(Main main) {
        this.peter = main.peter;
    }
}

class Peter extends Enemy {

    Enemy tom;

    Peter(Main main) {
        this.tom = main.tom;
    }
}

当main方法中的两个print方法运行时,第一个returns为null,因为分配给Enemy tom时Tom还没有创建. 为了解决这个问题,我没有在构造函数中将 TomPeter 分配给 Enemy,而是在创建两个 object 之后使用一个方法。 所以更像这样:

private void setEnemies(){
    peter.tom = tom;
    tom.peter = peter;
}

当在 println 方法之前调用该方法时,它可以完美运行。 我的问题是:有没有办法在创建 object 时设置敌人,这样我就不必在创建 object 后调用单独的方法?

简短的回答是:不,你不能。原因是您必须一次创建一个实例;当你创建第一个时,第二个还不存在,所以不能传递给第一个。

不过,这不应该是一个糟糕的限制。您想要向 Enemy class 添加一个 void setEnemy(Enemy myEnemy) 方法,然后为您的每个敌人调用它。像这样:

Enemy peter = new Peter();
Enemy tom = new Tom();
peter.setEnemy(tom);
tom.setEnemy(peter);

您不能在对象创建时设置它们,因为您是一个接一个地创建对象(Peter 和 Tom)。在创建第一个时,第二个仍然没有实例化。这样你就不能将第二个(尚未创建)传递给第一个。如果你像 Enemy peter=new Peter(); 这样创建它它将是 peter 对象的不同实例,因此它仍然不是您想要的

一般来说,引用一个还不存在的对象只能在一个尚未评估的函数中完成。这里java8可以来帮忙

Enemy peter = new Enemy(() -> tom);
Enemy tom = new Enemy(() -> peter);


public class Enemy {

    private final Supplier<Enemy> enemySupplier;

    public Enemy(Supplier<Enemy> enemySupplier) {
        this.enemySupplier = enemySupplier;
    }

    public Enemy enemy() {
        return enemySupplier.get();
    }

当然,在 peter 和 tom 的声明之间,peter 的 enemySupplier 也会 return null,但代码保证了这一点。如果构造函数仍然不对它的敌人做任何事情。

您可以使用 Domain driven design 方法。我使您的示例更通用一些,以向您展示它是如何工作的。

class Enemy {
    Enemy enemy;

    public Enemy createEnemy() {
        Enemy enemy = new Enemy();
        enemy.enemy = this;
        this.enemy = enemy;
    }
}

class Peter extends Enemy { }
class Tom extends Enemy { }

然后你会像这样使用它:

Peter peter = new Enemy();
Tom tom = peter.createEnemy();
System.out.println(peter.enemy); // returns Tom
System.out.println(tom.enemy); // returns Peter