可变对象是否仍然不变

时间:2014-09-03 12:09:53

标签: java constants

如果我有一个对象,请举例说明

public class Person {

    private int age;

    public Person(int age) {
        this.age = age;
    }

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

    public int getAge() {
        return age;
    }
} 

public static final Person PERSON = new Person(12);

因为我仍然可以改变年龄是不是被认为是不变的?

4 个答案:

答案 0 :(得分:5)

  

因为我仍然可以改变年龄是不是被认为是不变的?

PERSON是“常量”,因为它始终指向相同的 Person实例。但是,它所指向的Person实例不是常量,因为它可以被突变。这比术语更重要。

答案 1 :(得分:3)

它的引用是final(常量),但你仍然可以更新它的状态(实例变量),但你不能将它分配给其他Person对象。

JLS - 4.12.4. final Variables

下更好地解释
  

一旦指定了最终变量,它总是包含相同的值。

     

如果最终变量将reference保存到对象,则可以通过对象上的操作更改对象的状态,但变量将始终引用同一对象。

你不能说

person = new Person(20);

答案 2 :(得分:0)

把它想象成现实生活。你创建的PERSON是一个具体的人。您可以使用 PERSON user2896769 或使用一些独特的ID对其进行标记。当你通过这个标签引用对象时,你总是引用同一个对象(因为它是最终的),但是对象本身可以改变(就像现实中的人可能会变老,所以他们的年龄会发生变化)。

所以final意味着引用是常量,而不是对象本身是不可变的。 如果您希望PERSON完全不更改,则引用必须为final,并且引用指向的对象必须为immutable

当你写:

public static final Person PERSON = new Person(12);

这意味着从现在起PERSON将引用新创建的person对象。 并不意味着 PERSON 是新创建的人物对象。再次 - 表示它引用(指向)对象。这样你就可以引用一个对象了。而且这个引用是final,constant,总是指向同一个对象。但只要它是可变的,对象本身就可以改变。

答案 3 :(得分:0)

我认为PERSON是否是常量是一个语义问题,但它不被认为是“常量”,而是最终的对象引用。

另外,我会为变量选择正常的小写命名。在this question中对此进行了很好的讨论。

上述问题的答案之一引用了Effective Java,第2版,以下字段的标准是常数:

  

常量字段是静态最终字段,其值是不可变的。如果   静态final字段具有基本类型或不可变引用   键入(...),然后它是一个常量字段。