import java.util.Date;
public final class BrokenPerson
{
private String firstName;
private String lastName;
private Date dob;
public BrokenPerson( String firstName, public BetterPerson( String firstName,
String lastName, Date dob) String lastName, Date dob)
{ {
this.firstName = firstName; this.firstName = firstName;
this.lastName = lastName; this.lastName = lastName;
this.dob = dob; //error this.dob = new Date( dob.getTime() ); //correct
} }
public String getFirstName()
{
return this.firstName;
}
public String getLastName()
{
return this.lastName;
}
public Date getDOB() public Date getDOB()
{ {
return this.dob; //error return new Date( this.dob.getTime() );//correct
} }
}
上面的代码是在别人的博客上看到的,我能够理解在get一个Date类型的时候进行克隆,但是我不能理解在构造方法中的Date类型为什么还需要进行克隆之后才赋值给成员变量,也就是这句:this.dob = new Date( dob.getTime() );
我也是个菜鸟,不过大概也能猜到。如果你外部调用getDate之后,对获得的那个对象更改了,那么BrokenPerson里面的属性也就更改了,那就跟final不符了。
所以在getDate的时候才创建了这个对象的一个副本
这个类只提供了属性的get方法,外界只能获取这渪类的属性,但是Date这个属性给别人的是克隆的,那么其他类无论怎么修改这个克隆对象,我这个不变类中的这个属性都不受影响。否则的话,因为Date属性是对象,这个对象给了别人别人就可以随�'8F使用了。就不符合不变类的特点了。
构造函数丯对Date类型的数据赋值时是用克隆,避免外界修改原参数对象对该对象的影响。可以测试不使用克隆的结果:
1 把构造函数直接赋值:this.dob = dob;
2 编写测试类:
public static void main(String[] args){
Date date = new Date();
BrokenPerson b = new BrokenPerson("hello","world,date);
System.out.print(b.getDOB());
//修改date信息,可以看到BrokenPeron的dob属性值也被修改了,因为它与date是同一个引用。
date.setTime(System.currentMilliseconds());
System.out.print(b.getDOB());
}
我来回答你:
1--不可变的类和可变的类的区别:
从这个编成角度看就是加上 final 和不加 final的区别
从作用上看,不可变的类大多上是为了不让别的类继承,这也是很多书上写的。
但是为什么不让继承呢?
这个主要是为了实现这个Immutable模式的。也就是一个类的对象如果定义之后它的状态属性不会改变。例如String
这个是为多线程安全目的设计的。
使用final修饰的类一旦定义成Immutable模式那么它肯定线程安全的。不用进行额外的synchronized处理
2--克隆也就是拷贝
对于拷贝来说分为浅拷贝和深拷贝
浅拷贝就是只拷贝对象的地址,对象内部的属性数据共用
深拷贝就是连同对象内部的属性数据也拷贝。
那么区别你就可以看出来,浅拷贝之后的对象仍然可以修改被拷贝对象的数据。
一般我们定义一个对象的时候如果有子对象属性,定义这个get方法的时候容易写成浅拷贝。
外界程序通过get方法返回的值仍然可以修改该字对象的属性。
这个浅拷贝来实现克隆就不合适。因为前后不是独立的。
所以this.dob = new Date( dob.getTime() );
只是利用被拷贝对象dob的属性值来构造新的克隆对象dob
克隆使用深拷贝。