Java語言中有兩種不可變:引用不可變和對象不可變。
1. 引用不可變
final String str = "Hello"; // str = "World"; 這將導致編譯錯誤
這里的final
關鍵字表示str
引用的內存地址不可變,也就是說,不可以將str
指向另一個對象或修改指向的對象的值。
2. 對象不可變
final List<Integer> list = Arrays.asList(1, 2, 3); // list.add(4); 這將導致運行時錯誤
這里的final
關鍵字表示list
引用的內存地址不可變,而Arrays.asList()
返回的List對象本身也是不可變的,即不能增刪元素。這樣做的好處是可以保證多線程環境下對象安全,因為不可變對象在多線程環境下不需要額外的同步措施。
需要注意的是,雖然對象不可變,但是對象的屬性并不一定不可變。例如:
public final class Person { private final String name; // 不可變屬性 private int age; // 可變屬性 public Person(String name, int age) { this.name = name; this.age = age; } // 可變方法 public void setAge(int age) { this.age = age; } // 不可變方法 public String getName() { return name; } }
在上述代碼中,name
屬性是不可變的,而age
屬性是可變的。同時,setAge()
方法是可變方法,而getName()
方法是不可變方法。
因此,在Java語言中,要實現對象不可變需要遵循以下原則:
- 將屬性聲明為
private final
- 不提供修改屬性值的方法
- 如果要返回對象的屬性值,只能返回一個不可變的拷貝