Java 提供意外结果的用户定义的不可变类
这是关于我创建的一个不可变类。 详情如下:Java 提供意外结果的用户定义的不可变类,java,immutability,Java,Immutability,这是关于我创建的一个不可变类。 详情如下: final class ImmutableClass { private final Date d; public ImmutableClass(Date d) { this.d=d; } public Date getD() { return this.d; } Date is : Wed Dec 10 10:38:43 IST 2014, object is com.fedex.hrt.hrmai
final class ImmutableClass
{
private final Date d;
public ImmutableClass(Date d)
{
this.d=d;
}
public Date getD()
{
return this.d;
}
Date is : Wed Dec 10 10:38:43 IST 2014, object is com.fedex.hrt.hrmailbox.ImmutableClass@19616c7
New Date is : Mon Feb 10 10:38:43 IST 2014,New object is com.fedex.hrt.hrmailbox.ImmutableClass@19616c7
}
当我在下面的类中使用上面的类时:
public class UserClass
{
public static void main(String args[])
{
Date d1 = new Date();
ImmutableClass im= new ImmutableClass(d1);
System.out.print("Date is : " + im.getD() + ", object is " + im);//printing originals
//trying to change the date
d1.setMonths("10");
System.out.print("New Date is : " + im.getD() + ",New object is " + im);//printing latter ones
}
}
结果如下:
final class ImmutableClass
{
private final Date d;
public ImmutableClass(Date d)
{
this.d=d;
}
public Date getD()
{
return this.d;
}
Date is : Wed Dec 10 10:38:43 IST 2014, object is com.fedex.hrt.hrmailbox.ImmutableClass@19616c7
New Date is : Mon Feb 10 10:38:43 IST 2014,New object is com.fedex.hrt.hrmailbox.ImmutableClass@19616c7
ImmutableClass中的日期对象发生更改,即使对象相同,也不会创建新对象
这违反了不可变类的定义。
请说明我的方法是否错误,或者我是否遗漏了一些关于不变性的概念
问候 调用方仍然有对
日期的引用(并且可以修改其引用)。如果在构造函数中克隆()
它,则可以防止出现这种情况。像
public ImmutableClass(Date d)
{
this.d = (Date) d.clone();
}
另外,调用方可以修改您在getD
中返回的日期
,因此您也应该在那里克隆()
public Date getD()
{
return this.d != null ? (Date) this.d.clone() : null;
}
或者,对于日期
,存储它所包装的毫秒数
final class ImmutableClass {
private final long d;
public ImmutableClass(Date d) {
this.d = (d != null) ? d.getTime() : 0;
}
public Date getD() {
return new Date(d);
}
}
这仅在Date对象的情况下发生,在其他情况下,如String(class)、int(primitive)…调用getXXX()时返回原始值,即使我们更改了引用变量d…为什么行为不同?@sukhparmar发生这种情况是因为对象引用(按值传递引用仍然传递引用)。字符串是不可变的。原语类型和包装器类型都是一样的。现在我知道了,因为Date类是可变的。所以在返回它时要特别小心,就像你说的那样创建新实例。非常感谢Elliot