簡體   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