//java中对于基本类型可以使用“=”进行克隆,此时两个变量除了相等没有其他联系。对于引用类型不能通过简单的“=”进行克隆。这因为java内存空间的试用有关。
//java将内存分为栈和堆。栈中是基本类型和应用类型。堆中保存对象。栈中变量用后会立即回收,对象有虚拟机进行管理,回收时间有不确定性。这里要知道一个引用是可以指向一个对象的,注意引用是可以用“=”克隆的,但是这里克隆的是引用不是对象。也就是说一个引用对其对象值进行改变另一个引用所指向的对象值也相应变化了。这就是所谓的假克隆,见代码:
package cpoy;
public class false_copy {
public static void main(String[] args) {
Employee em1 = new Employee();
em1.setAge(10);
em1.setName("zc");
System.out.println("Original em1 " + em1);
Employee em2 = em1;
System.out.println("Original em2 " + em2);
em2.setAge(33);
em2.setName("cz");
System.out.println("Finally em1 " + em1);
System.out.println("Finally em2 " + em2);
}
}
class Employee{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "name: " + name + " age: " + age;
}
}
运行截图:
//这里谈一下浅克隆,对于基本类型和不可变类型的引用类型对其浅克隆后,若对基本类型进行克隆后的改变原对象没有任何变化,但是对引用类型改变后原对象中的应用类型会发生变化,因此在只有基本类型时可以用浅拷贝,若包含引用类型,或者说有复杂类类型要用深拷贝,下面见代码:
package cpoy;
class Address{
private String state;
private String province;
private String city;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Address(String state, String province, String city) {
// TODO Auto-generated constructor stub
this.state = state;
this.province = province;
this.city = city;
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuilder s = new StringBuilder();
s.append("state: " + state + ", ");
s.append("province: " + province + ", ");
s.append("city: " + city);
return s.toString();
}
}
class People implements Cloneable{
private String name;
private int age;
private Address ad;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAd() {
return ad;
}
public void setAd(Address ad) {
this.ad = ad;
}
public People(String name, int age, Address add) {
// TODO Auto-generated constructor stub
this.name = name;
this.age = age;
this.ad = add;
}
@Override
public People clone() {
// TODO Auto-generated constructor stub
People p = null;
try {
p = (People)super.clone();
} catch (CloneNotSupportedException e) {
// TODO: handle exception
e.printStackTrace();
}
return p;
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuilder s = new StringBuilder();
s.append("name: " + name + ", ");
s.append("age: " + age + ", ");
s.append("ad: " + ad);
return s.toString();
}
}
public class shallow_copy {
public static void main(String[] args) {
Address ad = new Address("China", "Shanxi", "Xian");
People p1 = new People("zc", 20, ad);
System.out.println("Pre clone P1's profile " + p1);
People p2 = p1.clone();
p2.getAd().setCity("Qingdao");
p2.getAd().setProvince("Shandong");
p2.getAd().setState("China");
p2.setAge(22);
p2.setName("cz");
System.out.println("P2's profile " + p2);
System.out.println("Cloned P1's profile " + p1);
}
}
运行截图:
//对于深克隆,当类中的域有除基本类型外的引用类型时,此时克隆要用到深克隆,克隆时要注意如果引用类型中还有可变的引用类型域,则该域也要进行克隆。 见代码(通过代码注意他和浅克隆的区别的地方):
package cpoy;
class deep_Address implements Cloneable{
private String state;
private String province;
private String city;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public deep_Address(String state, String province, String city) {
// TODO Auto-generated constructor stub
this.state = state;
this.province = province;
this.city = city;
}
@Override
public deep_Address clone(){
deep_Address dAddress = null;
try {
dAddress = (deep_Address)super.clone();
} catch (CloneNotSupportedException e) {
// TODO: handle exception
e.printStackTrace();
}
return dAddress;
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuilder s = new StringBuilder();
s.append("state: " + state + ", ");
s.append("province: " + province + ", ");
s.append("city: " + city);
return s.toString();
}
}
class deep_People implements Cloneable{
private String name;
private int age;
private deep_Address ad;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public deep_Address getAd() {
return ad;
}
public void setAd(deep_Address ad) {
this.ad = ad;
}
public deep_People(String name, int age, deep_Address add) {
// TODO Auto-generated constructor stub
this.name = name;
this.age = age;
this.ad = add;
}
@Override
public deep_People clone() {
// TODO Auto-generated constructor stub
deep_People p = null;
try {
p = (deep_People)super.clone();
p.ad = ad.clone();
} catch (CloneNotSupportedException e) {
// TODO: handle exception
e.printStackTrace();
}
return p;
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuilder s = new StringBuilder();
s.append("name: " + name + ", ");
s.append("age: " + age + ", ");
s.append("ad: " + ad);
return s.toString();
}
}
public class deep_clone {
public static void main(String[] args) {
deep_Address ad = new deep_Address("China", "Shanxi", "Xian");
deep_People p1 = new deep_People("zc", 20, ad);
System.out.println("Pre clone P1's profile " + p1);
deep_People p2 = p1.clone();
p2.getAd().setCity("Qingdao");
p2.getAd().setProvince("Shandong");
p2.getAd().setState("China");
p2.setAge(22);
p2.setName("cz");
System.out.println("P2's profile " + p2);
System.out.println("Cloned P1's profile " + p1);
}
}
运行截图: