所以為了避免這種情況發生,可以使用下列方式:
- new 一個新的 Point 物件,拷貝目前 Circle 物件內的 Point 物件資料。
- 將 Point 變成 immutable 的類別,也就是不提供設定(setXX ) method。
- Point 類別 implements Cloneable 類別,然後回傳 clone 物件。
範例程式:
class Point implements Cloneable {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
// 2. 把 setPoint 移除,讓 Point 變成 immutable 的類別
public void setPoint(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Circle {
private Point point;
private int radius;
public Circle(int x, int y, int r) {
point = new Point(x, y);
radius = r;
}
public Point getPoint() {
return point;
}
public Point getReadOnlyPoint() {
try {
// 3. 讓 Point 類別實作 Cloneable,然後回傳 clone 物件
return (Point)point.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
public Point getReadOnlyPoint2() {
//1. 使用 new 的方式,將目前的Point 資料拷貝一份
return new Point(point.getX(), point.getY());
}
@Override
public String toString() {
return String.format("(%d, %d) ,radius = %d", point.getX(), point.getY(), radius);
}
}
public class ProtectReferenceObj {
public static void main(String[] args) {
Circle circle = new Circle(1,1,2);
Point pt = circle.getPoint();
System.out.println("Before: " + circle);
pt.setPoint(10, 20);
System.out.println("After: " + circle);
System.out.println("================================");
System.out.println("Before: " + circle);
Point pt2 = circle.getReadOnlyPoint();
pt2.setPoint(11, 22);
System.out.println("After: " + circle);
System.out.println("pt2.x = " + pt2.getX() + " pt2.y = " + pt2.getY());
System.out.println("================================");
System.out.println("Before: " + circle);
Point pt3 = circle.getReadOnlyPoint2();
pt3.setPoint(55, 99);
System.out.println("After: " + circle);
System.out.println("pt3.x = " + pt3.getX() + " pt3.y = " + pt3.getY());
}
}
輸出結果:
Before: (1, 1) ,radius = 2 After: (10, 20) ,radius = 2 ================================ Before: (10, 20) ,radius = 2 After: (10, 20) ,radius = 2 pt2.x = 11 pt2.y = 22 ================================ Before: (10, 20) ,radius = 2 After: (10, 20) ,radius = 2 pt3.x = 55 pt3.y = 99
沒有留言:
張貼留言