-1

要创建一个不可变类,Effective Java 有最后一个条件。

要使类不可变,请遵循以下五个规则:

5-确保对任何可变组件的独占访问。如果您的类有任何引用可变对象的字段,请确保该类的客户端无法获取对这些对象的引用。切勿将此类字段初始化为客户端提供的对象引用,也不要从访问器返回对象引用。readObject在构造器、访问器和方法中制作防御性副本(第 24 条)

public final class ImmutableClass {


    private MutableObject mutableObject;

    // If I should not provide getter for this object. Then what is the use of this variable after I have
    //initalised in the constructor
}

有人可以向我解释这一点吗?

4

1 回答 1

3

它实际上相当简单。

基本上就是说不...

1- 提供对您的对象可能包含的任何可变对象的任何引用。

因此,如果您Class包含 ajava.util.List作为其字段之一,则任何使用您的客户都无法通过减速或某种获取器Class直接获得对该字段的引用。Listpublic

例如...

public class BadImmutableExample {
    public List<String> myStrings; // This can not be referenced by the client
    /*...*/
}

会很糟糕,因为myStrings任何机构都可以访问该字段以进行修改...

例如,如果您必须返回 in 中的值,则List要么需要返回 的副本List(而不是对它的引用),要么返回值的数组。

例如...

public class BadImmutableExample {
    private List<String> myStrings; // This can not be referenced by the client

    /*...*/

    public List<String> getMyStrings() {
        return myStrings;
    }
}

将向任何客户公开List myStrings,这将允许他们修改它。

在这种情况下,您还可以使用Collections.unmodifiableList(myStrings)使列表不可修改,return new ArrayList<String>(myStrings)或者返回一个数组String而不是...

2-永远不要将这样的字段初始化为客户提供的对象......

基本上这意味着,如果您Class要求客户为其提供某种或多种价值,您永远不应该直接维护它们的引用,而是再次制作副本供您自己参考......

例如...

public class BadImmutableExample {
    private List<String> myStrings; // This can not be referenced by the client

    public ImmutableExample(List<String> clientStrings) {
        myStrings = clientStrings;
    }
}

会打破这条规则,因为任何更改clientStrings都会立即反映在你的课堂上。

相反,您可以执行类似...

public class BetterImmutableExample {
    private List<String> myStrings; // This can not be referenced by the client

    public ImmutableExample(List<String> clientStrings) {
        myStrings = new ArrayList<String>(clientStrings);
    }
}

相反,它将制作客户提供的列表的副本,但不再反映对其所做的更改(客户提供的列表)

于 2013-08-16T05:45:59.590 回答