2015-12-09 29 views
4

我正在学习不可变的对象。我必须让下面的类不可变。我做对了吗?让一个类不可变

import java.awt.Point; 
public class MyImmutablePoint { 
    Point point; 

    public MyImmutablePoint(Point point) { 
     super(); 
     this.point = point; 
    } 

    public MyImmutablePoint() { 
     this (new Point (0,0)); 
    } 

    public Point getPoint() { 
     return point; 
    } 

    public void setPoint(Point point) { 
     this.point = point 
    } 
} 

“不可改变的” 类:

public final class MyImmutablePoint { 
    private final Point point; 

    public MyImmutablePoint(Point point) { 
     this.point = point; 
    } 

    public MyImmutablePoint() { 
     this (new Point (0,0)); 
    } 

    public Point getPoint() { 
     return point; 
    } 
} 

荫不能确定toString方法虽然。 也许返回像Point这样的对象可以像数组一样修改但不知道

+2

**格式化您的代码**。这是难以辨认的。 –

+0

问自己这个问题是:“*我可以在创建对象后改变对象的内部状态吗?*”。如果答案是*是*,那么你的对象是不可改变的。请记住,对象的内部状态是所有成员字段的内部状态的产物,因此如果任何*成员字段都是可变的,则对象需要非常小心地处理对该字段的访问,否则您的对象将是可变的。 – JonK

+0

@OP - 如果答案解决了您的问题,请考虑[接受](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)。这向社区其他人表明问题已经解决。 –

回答

6

没有

final Point p = new Point(0,0); 
final ImmutablePoint ip = new ImmutablePoint(p); 

两个例子:

//change the original Point passed in 
p.x = 10 
//use the getter and change the Point 
ip.getPoint().x = 10 

所以,首先你需要创建在构造函数中所采取的Point防守副本

public MyImmutablePoint(Point point) { 
    this.point = new Point(point); 
} 

然后,你需要创建Point的防守副本从getter返回:

public Point getPoint() { 
    return new Point(point); 
} 

这一切都使我认为它很可能是最好不要暴露内部point都:

public final class MyImmutablePoint { 

    private final Point point; 

    public MyImmutablePoint(Point point) { 
     this.point = new Point(point); 
    } 

    public MyImmutablePoint() { 
     this.point = new Point (0,0); 
    } 

    public int getX() { 
     return point.x; 
    } 

    public int getY() { 
     return point.y; 
    } 
} 

更多设置您的代码订购您的会员

+0

所以我应该给点一份副本? 哦,我想我不能给一个点的参考,但我不喜欢给int x,int y ,以便它MyImmutablePoint()或MyImmutablePoint(x,y) –

+0

好吧非常感谢你,我现在可以看到。 我猜不可变对象的定义是它的线程也是安全的。 所以我宁愿同步我的toString方法 –

+0

@TimoN。我不明白你的评论。不变性和线性只与切线相关。我定义的不可变对象是**不可变**。有关更多信息,请参见[Wikipedia](https://en.wikipedia.org/wiki/Immutable_object)。 –

5

不,它不是不可变的。点仍可以由MyImmutablePoint的创建者修改。例如:

Point point = new Point(1, 1); 
    MyImmutablePoint immutablePoint = new MyImmutablePoint(point); 
    point.setLocation(0, 0); 
+0

所以我应该给点一份副本?哦,我想我不能给一个点的参考,但我不喜欢给int x,int y,以便它的MyImmutablePoint()或MyImmutablePoint(x,y) –

+0

我将使用MyImmutablePoint(int x,int y)作为构造函数,而我认为我会基于那些返回时实例化一个新的Point。 get-method中的返回行不止是一个好习惯,但为了避免可变性,我可能会这样做。我不会做一个副本。 –