[英]How can I make the following class immutable?
I know I need to make Date
immutable.我知道我需要使Date
不可变。 However, I am not sure what else needs to be amended to ensure the class is immutable.但是,我不确定还需要修改什么以确保 class 是不可变的。 final
has been declared for the class and its methods. 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; }
}
There are several kinds of immutability.不变性有几种。 If you want standard immutability, that means every instance variable is final
and there are no setters.如果你想要标准的不变性,那就意味着每个实例变量都是final
的并且没有设置器。 If you want deep immutability, then your class must be immutable, but so must all of its instance variables.如果你想要深度不变性,那么你的 class 必须是不可变的,但它的所有实例变量也必须是不可变的。 Alternatively, you can have your getters only return copies of your instance variables (ensuring that they will never change within your class).或者,您可以让您的 getter 只返回实例变量的副本(确保它们永远不会在您的类中更改)。 However, this carries a not insignificant performance cost and can create technical debt later on.然而,这会带来不小的性能成本,并且会在以后产生技术债务。
I believe Date
class you are using in java.util.Date
.我相信您在 java.util.Date 中使用的Date
java.util.Date
。 So, Date is mutable in java (not sure what is the reason).因此,日期在 java 中是可变的(不确定是什么原因)。 So, you should return a copy of pubDate.因此,您应该返回 pubDate 的副本。
public Date getDate()
{
return pubDate.clone();
}
Also, A new class has added in LocalDate which is immutable.此外,在不可变的LocalDate中添加了一个新的 class。 I would suggest to use that if you your program does not require java.util.Date
specifically.如果您的程序不需要java.util.Date
,我建议您使用它。
EDIT: As per the suggestion in comment Date#clone can lead to problem as Date can be sub classed.编辑:根据评论中的建议 Date#clone 可能会导致问题,因为 Date 可以被分类。 Use new Date(pubDate.getTime())
for copying the Date object.使用new Date(pubDate.getTime())
复制日期 object。
The best advice I could give you is to use Instant
(or LocalDateTime
or ZonedDateTime
) in place of a Date
because Instant
(and the other java.time
classes) are immutable.我能给你的最好建议是使用Instant
(或LocalDateTime
或ZonedDateTime
)代替Date
因为Instant
(和其他java.time
类)是不可变的。 Date
is obsolete and should no longer be used. Date
已过时,不应再使用。 But, if you need to stick to this code then you could do defensive copies , something like the following:但是,如果您需要坚持使用此代码,那么您可以执行防御性副本,如下所示:
public Journal(Article [] contents, Date d) {
// ...
pubDate = new Date(d.getTime());
}
// ...
public Date getDate() {
return new Date(pubDate.getTime());
}
Notice here that the Date.clone
method was not used .注意这里没有使用Date.clone
方法。 This is because Date
is non-final, so the clone
method is not guaranteed to return an object whose class is java.util.Date
, it could return an instance of an untrusted subclass that is specifically designed with malicious intentions.这是因为Date
是非最终的,所以clone
方法不能保证返回一个 object 其 class 是java.util.Date
,它可能返回一个不可信的子类的实例,该子类是专门为恶意设计的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.