如何在调用者无法编辑返回对象的地方实现 getter?

How do I implement a getter where the caller can't edit the returned object?

我想制作一个 getter 不允许调用者编辑 returned 对象。

List 为例(尽管我希望答案也适用于任何其他类型),这是 returning 和编辑属性的常用方法:

class MyClass {
    private List<String> strings;

    // to get the whole object
    public List<String> getStrings() {
        return this.strings;
    }

    // to alter the object
    public void addString(String newStr) {
        this.strings.add(newStr);
    }

    //...
}

然而,这并不能阻止其他一些 class 这样做

myClassInstance.getStrings().add("that's a dumb implementation, bro");

这有点粗鲁,因为我为此特定目的创建了 addString()

我宁愿其他 classes 只使用 getStrings() 方法来读取,因为可能有类似的情况我不想实现 addString()方法。在那种情况下,其他 classes 无论如何都可以通过 getter 编辑 strings,但我仍然希望能够在 C [=] 中私下编辑对象56=].

我知道如果属性是原始类型这不会有问题,因为它们直接保存在实例中,但对象是对内存的引用,所以任何 class 能够得到它的手如果对象类型允许,可以对这些引用进行编辑。

您可以使用 getStrings return 一个不可修改的列表。

public List<String> getStrings() {    
    return Collections.unmodifiableList(this.strings);
}

https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#unmodifiableList(java.util.List)

Can I just trust that other classes won't try to edit my object through the getter?

没有

There's the option of cloning it (some classes may override the clone() method), but is this a good use for clone()? What are the best practices of cloning an object?

oracle 文档提供了一个建议的策略:

  • Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods. (https://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html)

Is it worth it to create a custom class (called ReadOnlyList, for this example) that is only writeable in the constructor (like this), then copy my strings to a new ReadOnlyList, and return that?

在这种情况下不是(请参阅 Micky Loo 的回答)。但是在更特殊的情况下是的(如果你必须保证不变性并且不能复制对象)。

Also, should objects provide a method that returns a non-writable clone of the object to solve this?

您不能在 Java 中创建 const return 值。参见:Const return values in Java