Cuối cùng không giống như không thay đổi.
final != immutable
Từ khóa final
được sử dụng để đảm bảo rằng các tài liệu tham khảo không được thay đổi (có nghĩa là, các tài liệu tham khảo nó đã không thể được thay thế bằng một cái mới)
Nhưng, nếu thuộc tính là tự có thể sửa đổi được, bạn có thể làm những gì bạn vừa mô tả.
Ví dụ
class SomeHighLevelClass {
public final MutableObject someFinalObject = new MutableObject();
}
Nếu chúng ta nhanh chóng lớp học này, chúng tôi sẽ không thể gán giá trị khác cho các thuộc tính someFinalObject
vì nó là thức.
Vì vậy, đây là không thể:
....
SomeHighLevelClass someObject = new SomeHighLevelClass();
MutableObject impostor = new MutableObject();
someObject.someFinal = impostor; // not allowed because someFinal is .. well final
Nhưng nếu đối tượng tự nó là có thể thay đổi như thế này:
class MutableObject {
private int n = 0;
public void incrementNumber() {
n++;
}
public String toString(){
return ""+n;
}
}
Sau đó, giá trị chứa bởi đối tượng có thể thay đổi có thể được thay đổi.
SomeHighLevelClass someObject = new SomeHighLevelClass();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
System.out.println(someObject.someFinal); // prints 3
này có tác dụng tương tự mà bài viết của bạn:
public static void addProvider(ConfigurationProvider provider) {
INSTANCE.providers.add(provider);
}
Ở đây bạn không thay đổi giá trị của Ví dụ, bạn đang thay đổi trạng thái nội bộ của mình (thông qua, phương pháp providers.add)
nếu bạn muốn ngăn chặn rằng định nghĩa lớp học phải được thay đổi như thế này:
public final class ConfigurationService {
private static final ConfigurationService INSTANCE = new ConfigurationService();
private List providers;
private ConfigurationService() {
providers = new ArrayList();
}
// Avoid modifications
//public static void addProvider(ConfigurationProvider provider) {
// INSTANCE.providers.add(provider);
//}
// No mutators allowed anymore :)
....
Nhưng, nó có thể không có ý nghĩa nhiều :)
Nhân tiện, bạn cũng phải synchronize access to it về cơ bản vì lý do tương tự.
Nhận thức sai này xuất hiện khá thường xuyên, không nhất thiết phải là câu hỏi. Thường là câu trả lời hoặc bình luận. – Robin
Giải thích đơn giản từ JLS: ** "Nếu biến cuối cùng chứa tham chiếu đến đối tượng, thì trạng thái của đối tượng có thể bị thay đổi bởi thao tác trên đối tượng, nhưng biến sẽ luôn tham chiếu đến cùng một đối tượng." ** [Tài liệu JLS] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4) – realPK