gpt4 book ai didi

java - 为什么在不可变类中的 getter 中制作防御性副本?

转载 作者:太空狗 更新时间:2023-10-29 22:36:55 26 4
gpt4 key购买 nike

这个问题是关于良好的编程实践和避免潜在的漏洞。
我读了 Joshua Bloch 的 Effective Java,我想知道的是:
为什么我应该考虑在我的不可变类中的 getter 方法中制作防御性副本,其中没有修改器?
第二:除了 private 之外,我为什么还要将我的字段设置为 final ?这仅与性能有关(与安全性无关)吗?

最佳答案

我相信这种情况可以证明这种说法:

public class Immutable {

private final String name;

private Date dateOfBirth;

public Immutable(String name, Date dateOfBirth) {
this.name = name;
this.dateOfBirth = dateOfBirth;
}

public String getName() {
return name;
}

public Date getDateOfBirth() {
return dateOfBirth;
}

}

getName() 很好,因为它也返回不可变对象(immutable对象)。但是 getDateOfBirth() 方法可能会破坏不变性,因为客户端代码可以修改返回的对象,从而也修改 Immutable 对象:

Immutable imm = new Immutable("John", new Date());

imm.getName(); //safe
Date dateOfBirth = imm.getDateOfBirth();
//hundreds of lines later
dateOfBirth.setTime(0); //we just modified `imm` object

返回不可变对象(immutable对象)和基元是安全的(因为它们是按值返回的)。但是,您需要制作可变对象的防御性副本,例如 Date:

public Date getDateOfBirth() {
return new Date(dateOfBirth.getTime());
}

并将集合包装在不可变 View 中(如果它们是可变的),例如见Collections.unmodifiableList() :

public List<Integer> getSomeIds() {
return Collections.unmodifiableList(someIds);
}

关于java - 为什么在不可变类中的 getter 中制作防御性副本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10951820/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com