大学の Java の授業中に、パブリック ゲッターがプライベートな可変オブジェクトへの参照を返す、プライバシー リークの概念について学びました。
彼らが示した例は次のとおりです。
private HashSet<*> priv = new HashSet<*>
public Collection<*> getPriv () {
return this.priv;
}
ここでの問題は、オブジェクトのクライアントがプライベート HashSet を意図的またはその他の方法で破損する可能性があることです。
コースでは、提案された解決策は次を使用することでした。
public Collection<*> getPriv () {
return Collections.unmodifiableCollection (this.priv);
}
オブジェクトの内部状態が外部の変更から保護されるだけでなく、返された unmodifiableCollection を変更しようとすると例外がトリガーされるため、これは私には良い解決策のように思えます。ただし、これの問題は、コレクションでのみ機能することです。他の変更可能な Java クラスに相当するものはないようです。
それ以来私が読んだ Java に関するほとんどの本は、次のことを示唆しています。
public Collection<*> getPriv () {
return this.priv.clone ();
}
これは複製可能なオブジェクトで機能しますが、返されたオブジェクトはクライアント オブジェクトのコンテンツに変更できます。オブジェクトの内部状態は引き続き保護されますが、実際には変更できないデータを変更しようとしても例外が発生しなくなりました。これは、プライベート コレクションを取得してそれを変更し、なぜ変更がオブジェクトに反映されないのか分からないというミスを犯す可能性があることを意味します。 (不変であるべきクローンの変更)。
return Collections.unmodifiableCollection (this.priv);
任意のクラス (または少なくともクローン可能な実装などの前提条件を満たしている任意のクラス) で機能する、より一般化された方法はありますか、またはすべてのプライベート クラスの可変バージョンと不変バージョンを実装する唯一のオプションです。ゲッターを介して公開しますか?