java中的不可变类

iAm*_*ing 1 java immutability

是否需要将Immutable类的字段设置private为标记为final,不能更改?
我的意思是仅仅标记字段是不够的final?

(我知道不可变类没有必要有最终字段,但建议在内部编译时检查类.)

Bor*_*der 7

不,这还不够.

考虑这个例子:

final class ImmutableClass {
    private final List<String> data;

    public ImmutableClass(final List<String> data) {
        this.data = data;
    }

    public List<String> getData() {
        return data;
    }
}
Run Code Online (Sandbox Code Playgroud)

这个类是final如此无法扩展.它的data字段final在分配后无法更改.

但是:

final ImmutableClass immutableClass = new ImmutableClass(data);
immutableClass.getData().add("Some other value");
Run Code Online (Sandbox Code Playgroud)

哎呀.

因此,要使一个类真正不可变,所有字段也应该是不可变类,或者具有防御性副本.

例如,要纠正有关您的问题,您需要执行以下操作:

final class ImmutableClass {
    private final List<String> data;

    public ImmutableClass(final List<String> data) {
        this.data = new ArrayList<>(data);
    }

    public List<String> getData() {
        return Collections.unmodifiableList(data);
    }
}
Run Code Online (Sandbox Code Playgroud)

这只能起作用,因为它String是不可变的.例如,如果你有a,List<Date>你还需要复制单个Date对象.