【问题标题】:Java pass two object to each others in one stepJava一步将两个对象相互传递
【发布时间】:2016-08-04 09:40:46
【问题描述】:

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

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

和下面的父类:

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

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

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

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

【问题讨论】:

  • 请注意,您描述的问题是因为Peter peter = new Peter(this);不安全发布 的示例:您在@ 之前将Main 引用传递给Peter 的构造函数987654332@ 已完全初始化。这意味着Peter 可以在Main 处于有效状态之前开始使用它,因此可能会导致之前的意外和不可预测。
  • 我知道在我当前的项目中,我从另一个类的构造函数中创建了 PeterTom。我以这种方式发布它以简化代码。
  • RadioButtons 也做了同样的事情,将一个 RadioButtonGroup 添加到他们的构造/作为工厂。然后 RadioButtonGroup 确保所有单选按钮相互关联,

标签: java class object creation


【解决方案1】:

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

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

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

【讨论】:

    【解决方案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
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        一般来说,引用仍然不存在的对象只能在尚未评估的函数中完成。这里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();
            }
        

        当然,在声明peter 和tom 之间,peter 的enemySupplier 也会返回null,但这是由代码保证的。如果构造函数仍然没有对它的敌人做任何事情。

        【讨论】:

          猜你喜欢
          • 2012-10-18
          • 2021-06-02
          • 2011-11-17
          • 1970-01-01
          • 2015-04-06
          • 2021-09-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多