【问题标题】:Why this code is not printing 30, since int is primitive and mutable?为什么这段代码不打印 30,因为 int 是原始且可变的?
【发布时间】:2015-03-08 13:19:50
【问题描述】:
package com.test;

public class Person {

    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


}


package com.test;

public class Test {

    public static void main(String[] args) {

        Person person1 = new Person();
        person1.setAge(10);

        Person person2 = new Person();
        person2.setAge(person1.getAge());

        person1.setAge(30);

        System.out.println(person2.getAge());

    }
}

我认为这将打印 30,因为 int 是原始且可变的。

谁能解释一下为什么?

我不是不小心在这里打印了 person2。我需要了解其背后的真正概念。

现在我正在检查与包装器相同的内容。但结果是一样的。

package com.test;

public class Person {

    private Integer age;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }


}

甚至尝试使用可变的 Date 类:

package com.test;

import java.util.Date;

public class Person {

    private Date date;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

}


package com.test;

import java.util.Date;

public class Test {

    @SuppressWarnings("deprecation")
    public static void main(String[] args) {

        Person person1 = new Person();
        person1.setDate(new Date(2015, 3, 8));

        Person person2 = new Person();
        person2.setDate(person1.getDate());

        System.out.println("Person2 date before modifying " + person2.getDate());

        person1.setDate(new Date(2015, 3, 9));

        System.out.println("Person2 date after modifying " + person2.getDate());

    }
}

这打印:

修改前的 Person2 日期 Thu Apr 08 00:00:00 IST 3915
Person2 修改后的日期 Thu Apr 08 00:00:00 IST 3915

【问题讨论】:

  • 可能想谷歌 java 通过引用传递与通过值传递。

标签: java


【解决方案1】:

为什么这段代码不打印 30

因为您输出的是 person2age 字段,而您从未将其设置为 30。您将 person1age 字段设置为 30,但不是person2。实例字段是特定于实例的。

特别是,如果您希望这一行在实例之间创建一些链接:

person2.setAge(person1.getAge());

它没有。它获取person1age 字段的,然后将该(此时为10)分配给@ 的age 字段987654332@。它们之间没有持续的联系。

详细介绍:

Person person1 = new Person();        // Creates a Person instance
person1.setAge(10);                   // Sets person1's age to 10

Person person2 = new Person();        // Creates a separate Person instance
person2.setAge(person1.getAge());     // Sets person2's age to 10

person1.setAge(30);                   // Sets person1's age to 30; no effect on person2

System.out.println(person2.getAge()); // Shows person2's age (10)

...因为 int 是原始且可变的?

int 是原始的;你可以争辩说它是可变的,如果你把 mutable 理解为它通常的意思:拥有可以改变的状态。 ints 没有。 555 并且不能更改。 包含 int 值的变量可以更新为包含不同 int 值,但这是在更改变量,而不是 int

相比之下,对象的状态可以在不改变引用它们的变量的情况下改变:

// Create a LinkedList and save a reference to it in `list`
List<String> list = new LinkedList<String>();

// Change the state of the list
list.add("Foo");

在上面的第二个语句中,变量 list 没有改变;它仍然包含对同一列表的引用。该语句会更改列表的状态(而不是引用它的变量的状态)。

【讨论】:

  • 感谢您的回答。我想知道为什么人们突然投了同样的票。所以这与对象引用无关??我很困惑!!你能解释一下吗?
  • @Valath:对什么感到困惑?
  • 我的想法与以下答案相同。所以这是错的吧?由于整数是不可变的,我认为这是给 10。如果它是一个日期,一个可变对象会以相反的方式表现吗?
  • @Valath:如果您使用可变对象并更改其状态,而不是更改指向它的变量的内容,那么无论您使用哪个引用,您都会看到效果。但是,如果您按照上面所做的操作,将 new 值分配给变量,则不会。例如,看看我上面的list 示例。如果我在第二行做了list = new LinkedList&lt;String&gt;();,那么我将更改变量,而不是它所引用的对象的状态。
  • 即使我现在尝试使用可变日期。它也像你说的那样工作。所以我认为每个对象在堆中都有不同的内存位置。在不调用 setter 的情况下修改其他值不会修改相互关联的值,就像我的一样。有没有机会陷入我上面在 java 中解释的情况?
【解决方案2】:

您的代码不能精确地打印 30,因为 int 是基本类型,而不是对象/引用数据类型,例如 Integer
这导致每个 Person 对象实例都包含其自己的年龄值,并且这些值不共享。 如果年龄被定义为 Integer 而不是 int(以及 setAge 方法参数),您的代码将打印 30:

public class Person {

    private Integer age;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

【讨论】:

  • 我认为您需要在这里重新考虑。这是行不通的。请参阅有关上述答案的讨论。
  • 我相当肯定它会起作用。您似乎没有正确掌握原始类型和对象类型之间的区别... Integer 是一个“封装” int 的类,因此可以像 T.J. 中的 List&lt;String&gt; 一样对待它。克劳德的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2022-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多