如何使以下类不可变?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使以下类不可变?相关的知识,希望对你有一定的参考价值。
我知道我需要使Date
不可变。但是,我不确定是否需要修改其他内容以确保该类是不变的。已经为该类及其方法声明了final
。
public final class Journal
private final Set<Article> edition;
private final Date pubDate;
public Journal(Article [] contents, Date d)
edition = new TreeSet<Article>();
for(int i=0; i <contents.length; i++)
edition.add(contents[i]);
pubDate = d;
public Set<Article> getArticles()
return Collections.unmodifiableSortedSet(edition);
public Date getDate() return pubDate;
[我能给您的最佳建议是使用Instant
(或LocalDateTime
或ZonedDateTime
)代替Date
,因为Instant
(和其他java.time
类)是不可变的。 Date
已过时,不应再使用。但是,如果您需要坚持执行此代码,则可以执行防御副本,如下所示:
public Journal(Article [] contents, Date d)
// ...
pubDate = new Date(d.getTime());
// ...
public Date getDate()
return new Date(pubDate.getTime());
这里注意Date.clone
方法是未使用。这是因为Date
是非最终的,因此无法保证clone
方法返回其类为java.util.Date
的对象,它可能会返回专门为恶意目的而设计的不受信任子类的实例。
我相信您正在Date
中使用java.util.Date
类。因此,Date在Java中是可变的(不确定原因是什么)。因此,您应该返回pubDate的副本。
public Date getDate()
return pubDate.clone();
此外,LocalDate中添加了一个不可变的新类。如果您的程序不需要java.util.Date
,则建议使用该选项。
EDIT:根据评论中的建议Date#clone可能会导致问题,因为Date可以被分类。使用new Date(pubDate.getTime())
复制Date对象。
有几种不变性。如果要实现标准不变性,则意味着每个实例变量均为final
,并且没有设置器。如果要实现高度不变性,则您的类必须是不变的,但是其所有实例变量也必须不变。另外,您可以让您的getter只返回实例变量的副本(确保它们在您的类中永远不会改变)。但是,这带来不小的性能成本,并且以后可能会造成技术债务。
以上是关于如何使以下类不可变?的主要内容,如果未能解决你的问题,请参考以下文章