4 回答

TA貢獻1757條經驗 獲得超8個贊
如果您的 getter 方法返回對可變對象的引用,那么這會大大削弱您的類提供的封裝質量,因為可以在不調用類的方法的情況下修改類實例的狀態。
防止此問題的一種標準策略是 J. Bloch 所說的防御性副本(Effective Java,第 3 版,第 50 項:“在需要時制作防御性副本”)。
var
這意味著在 getter 方法中創建一個副本,然后返回該副本。如何做到這一點取決于A
.
因為A
是類型參數,制作實例的副本需要設計上的額外支持。要了解如何使用 Java 的克隆機制實現此目的,請參閱我對帖子“創建類型接口而不是使用有意義嗎?”的回答。Copyable
Cloneable

TA貢獻1856條經驗 獲得超17個贊
我要在這里補充一點:正如其他人所說,您分發對象引用并且可以對其進行修改,這可能很糟糕。
面向對象是關于將數據和處理數據的代碼保存在一個地方。如果您需要 getter,請考慮 getter 的調用者需要做什么,以及該操作是否應該是具有數據的類上的方法。您的代碼可能會遇到Feature Envy代碼異味,因為它違反了告訴,不要詢問原則。
要解決此問題,請移除 getter,并根據需要引入新方法。例如,如果您有一些需要打印的數據對象,您可以將 Printer 傳遞給對象并讓它自己打印到給定的 Printer。
如果你正在處理一個集合類(只是從你的模板參數中猜測),你可能需要保留 getter,但是你可能并不關心調用者無論如何都會改變值。

TA貢獻2051條經驗 獲得超10個贊
對于剛開始的人來說,這可能有點過于詳細,但您可能會回顧 class java.util.concurrent.atomic.AtomicReference<V>,這與您的示例非常相似。
一般來說,將實例變量放在私有變量中,同時使用 getter 和 setter 提供對變量的訪問是標準做法。
請注意,您的類名應該大寫,類型參數“V”更標準,變量名通常是“值”。此外,嘗試為班級選擇一個更具交際性的名稱。(類型參數類型變量可以是“ValueType”,這符合某些偏好。但是,單個字符類型變量名稱更常見。)
public class Wrapper<V> {
private V value;
public V get() {
return value;
}
public void set(V value) {
this.value = value;
}
}

TA貢獻1829條經驗 獲得超6個贊
如果這是一個問題,您可以創建一個外觀來保護您的變量
public class Facade extends A {
A myObj;
public Facade (A obj) {
myObj =
}
public A get(){
return myObj.get();
}
public B set(Object val) {
throw new RuntimeException("Setting is not allowed");
}
}
添加回答
舉報