所以為了避免這種情況發生,可以使用下列方式:
- 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
沒有留言:
張貼留言