【问题标题】:Confusion when setting an Object equal to another设置一个对象等于另一个对象时的困惑
【发布时间】:2013-11-30 09:54:50
【问题描述】:

假设我有一个 Dog 类,我创建了两个 Dog 实例,如下所示:

Dog dog1 = new Dog();

Dog dog2 = dog1;

如果我使用

dog1.shower();

dog2 也会执行呼叫吗?如果是这样,如何防止dog2 调用相同的方法?

【问题讨论】:

    标签: java oop


    【解决方案1】:

    通过编写Dog dog2 = dog1;,您声明了一个引用 dog2,它将指向与dog1 相同的对象。

    因此,调用 dog1.shower();dog2.shower(); 将导致相同的行为(在同一 Dog 对象上调用 shower() 方法)。

    如果你写

    Dog dog2 = new Dog();
    

    您让您的 dog2 引用另一个新创建的 Dog 对象。

    编辑
    如果您需要dog2 引用不同的Dog 并获得dog1 的所有品质,您可以选择:

    • 按照 chrylis 的建议创建一个 copy constructor。 完成此操作后,您可以编写:

      // dog2 refers to new copy of `Dog`, identical to original dog1
      Dog dog2 = new Dog(dog1); 
      
    • Override Object.clone() 在你的班级Dog。在这种情况下,您将拥有:

      // dog2 refers to new copy of `Dog`, identical to original dog1
      Dog dog2 = dog1.clone(); 
      

    我认为您也可以通过这些选项的简单示例来参考 Edgar 的回答。

    【讨论】:

    • 如果我做了 Dog dog2 = new Dog();然后dog2 = dog1,会导致同样的问题吗?还是 dog2 会获得 dog1 的所有品质,但会引用不同的 Dog?
    • 不,你会遇到同样的问题。当您执行 dog2 = dog1; 时,您将重新分配引用,并且 dog2 将再次指向与 dog1 完全相同的对象
    • @xheyhenry 使用赋值运算符= 使变量指向Dog 的特定实例。如果您说Dog dog2 = new Dog(); dog2 = dog1;,那么dog2 现在指向与dog1 相同的Dog,并且您输入dog2new Dog() 被丢弃。如果要复制 Dog 及其所有属性,则需要编写 复制构造函数
    【解决方案2】:

    会发生这样的事情:

    Dog dog1 = new Dog();
    

    Dog dog2 = dog1;
    

    当您调用dog1.shower(); 时,会发生一次阵雨,因为它发生在同一个对象上。

    您应该创建另一个狗 Dog dog2 = new Dog(); 的实例,这样他们就不会最终给同一只狗洗澡。

    【讨论】:

      【解决方案3】:

      在您的情况下,dog2 只是“指向”dog1。无论您在dog1 中更改什么(因为它是同一个对象),都将在dog2 中更改,反之亦然。

      你可能想做的是为你的狗实现一个复制功能,如果你想让一只狗具有相同的属性值,但那不是同一个对象:

       public Dog clone() {
           Dog dog = new Dog();
           // now write all the attributes from the current dog, into this new dog
           return dog;
       }
      

      然后像这样创建 dog2:

       dog2 = dog1.clone();
      

      你也可以把它移到 Dog 的构造函数中:

       public Dog(Dog dogToClone) {
           // here take all attributes from dogToClone and add them to this dog.
       }
      

      你的电话是:

       dog2 = new Dog(dog1);
      

      【讨论】:

        【解决方案4】:

        在您的示例中,dog2 不作为单独的狗存在,它与 dog1 是同一只狗。所以这只狗会洗澡,而且只会洗澡一次。

        【讨论】:

        • +1 强调Dog 将只有一个淋浴:)
        【解决方案5】:

        简单地不要分配Dog dog2 = dog1;,而是创建一个新对象并重新分配dog2dog1的所有属性。

        Dog dog2 = new Dog();
        //Assign all the properties of dog1 to dog2 manually
        

        当您分配dog2 = dog1 时,这并不意味着您正在创建一个新对象,而是您只是在创建对同一对象的引用,即两个对象都是相同的。

        【讨论】:

          【解决方案6】:

          在您的情况下, dog1 和 dog2 指的是同一个 Dog 对象。 dog1 和 dog2 是堆栈上的引用,它们指向驻留在堆上的对象。 所以调用任何一个都将修改驻留在堆上的单个 Dog 对象。 如果您不希望这样做,请为 Dog 2 创建一个新对象并将 dog1 的内容一一复制到 dog2。

          【讨论】:

            【解决方案7】:

            dog 1 引用了 Dog() 的一个实例,而 dog 2 也引用了同一个实例,因此整体交替一个可能会交替另一个。如果你不想让任何一只狗干扰另一只狗,你可以在每个变量中创建一个 Dog 的新实例

                 Dog dog1=new Dog(), dog2= new Dog();
            

            这可能会解决您的问题。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2014-04-15
              • 1970-01-01
              • 2010-12-29
              • 1970-01-01
              • 1970-01-01
              • 2016-03-21
              相关资源
              最近更新 更多