Java只需一步就可以将两个对象传递给对方

时间:2016-08-04 09:40:47

标签: java class object creation

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

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 Enemy {
     //some variables
}

并跟随两个子课程:

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方法中运行时,第一个返回null,因为Tom在分配给Enemy tom时没有创建。 为了解决这个问题,我没有在构造函数中将TomPeter分配给Enemy,而是在创建两个对象之后使用方法。 更像这样:

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

当在println方法之前调用该方法时,它可以完美地工作。 我的问题是:有没有办法在对象创建时设置敌人,所以我不必在创建对象后调用单独的方法?

4 个答案:

答案 0 :(得分:6)

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

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

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

答案 1 :(得分:2)

您可以使用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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

通常,引用仍然不存在的对象只能在尚未评估的函数中完成。在这里,java 8可以提供帮助。

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

当然,在彼得和汤姆的声明之间,彼得的敌人供应商也将返回null,但这是由代码保证的。如果构造函数仍然没有对其敌人做任何事情。