繁体   English   中英

如何使以下 class 不可变?

[英]How can I make the following class immutable?

我知道我需要使Date不可变。 但是,我不确定还需要修改什么以确保 class 是不可变的。 final已声明为 class 及其方法。

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; }
}   

不变性有几种。 如果你想要标准的不变性,那就意味着每个实例变量都是final的并且没有设置器。 如果你想要深度不变性,那么你的 class 必须是不可变的,但它的所有实例变量也必须是不可变的。 或者,您可以让您的 getter 只返回实例变量的副本(确保它们永远不会在您的类中更改)。 然而,这会带来不小的性能成本,并且会在以后产生技术债务。

我相信您在 java.util.Date 中使用的Date java.util.Date 因此,日期在 java 中是可变的(不确定是什么原因)。 因此,您应该返回 pubDate 的副本。

public Date getDate() 
{
 return pubDate.clone();
}

此外,在不可变的LocalDate中添加了一个新的 class。 如果您的程序不需要java.util.Date ,我建议您使用它。

编辑:根据评论中的建议 Date#clone 可能会导致问题,因为 Date 可以被分类。 使用new Date(pubDate.getTime())复制日期 object。

我能给你的最好建议是使用Instant (或LocalDateTimeZonedDateTime )代替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方法不能保证返回一个 object 其 class 是java.util.Date ,它可能返回一个不可信的子类的实例,该子类是专门为恶意设计的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM