Java 为什么可以更改最终对象的值?

Java 为什么可以更改最终对象的值?,java,class,object,final,setter,Java,Class,Object,Final,Setter,我有一个Java类的观点。为了快速访问点0,0,我为它提供了一个常量 public class Point{ //... public static final Point NULLPOINT=new Point(0, 0); //... } 但是,此Point.NULLPOINT.setXx仍然有效,并将NULLPOINT更改为x,0。有没有办法防止这种情况?我原以为final会阻止这种情况发生,但显然我高估了它的威力。final保证引用不会更改,即您将无法将另一个点

我有一个Java类的观点。为了快速访问点0,0,我为它提供了一个常量

public class Point{
    //...
    public static final Point NULLPOINT=new Point(0, 0);
    //...
}

但是,此Point.NULLPOINT.setXx仍然有效,并将NULLPOINT更改为x,0。有没有办法防止这种情况?我原以为final会阻止这种情况发生,但显然我高估了它的威力。

final保证引用不会更改,即您将无法将另一个点对象重新指定给NULLPOINT reference。但仍然可以更改对象状态。如果需要确保NULLPOINT状态不会更改,则应使Point类不可变:例如,删除setters。

因为Java中的所有对象变量都是对对象的引用,使NULLPOINT成为final意味着没有人可以更改NULLPOINT引用的点。java.awt.Point类是可变的,但是您可以做一些事情来实现类似的效果

首先,可以声明NULL_X和NULL_Y值,并将任何其他点的X和Y值与这些值进行比较。其次,您可以使用无设置器的NULLPOINT所需的所有方法实现一个ImmutablePoint类。第三,可以编写一个nullpoint函数,返回0,0处的新点


所有这些选项在性能和易用性方面都有其优点和缺点。

您没有更改对象引用,但其内部属性最终标记表示变量NULLPOINT不能重置为指向另一个点,并不是说现有的NULLPOINT的内容不能更改。我认为如果您说引用是最终的,而不是引用处的内容,会更清楚。ImmutablePoint结果似乎很好,如果你知道我想说什么的话,有没有一种方法可以让所有的二传手都不被空的凌驾于他们之上,而让他们从遗嘱中消失?我相信空的凌驾于他们之上是唯一的方法,这是一个丑陋的解决方案。此外,Point的x和y字段是公共的,因此即使没有这些方法,它们也可以更改。