深度克隆与浅度克隆在java中,无法使用类直接赋值,即使用LoginloginBloginA这样的赋值方式,虽然编译起来
深度克隆与浅度克隆
在java中,无法使用类直接赋值,即使用LoginloginB=loginA;这样的赋值方式,虽然编译起来是没有错的,但往往与实际用法出现叉错.本意是new一个新类出来,将LoginA的值赋给LoginB,但是,这时候,你会发现,如果你修改了LoginB的值,loginA的值也会随之而改变,这是因为什么呢?
???其实这个原因很简单,因为java不同C语言类的有指针,java是通过直接指向内存的引用而调用对象的
如图:
?

?由图可以看出,对像LoginB仍然指向LoginA的堆空间?为了解决这种情况,我使用如下的例子:先定义User类public class User {
?private int id;
?private String userName;
?private String password;
?
?public int getId() {
??return id;
?}
?public void setId(int id) {
??this.id = id;
?}
?public String getUserName() {
??return userName;
?}
?public void setUserName(String userName) {
??this.userName = userName;
?}
?public String getPassword() {
??return password;
?}
?public void setPassword(String password) {
??this.password = password;
?}
?}
再定义Login类
public class Login implements Cloneable {
?
?private int id;
?private String loginIp;
?private User loginUser;
?
?public int getId() {
??return id;
?}
?public void setId(int id) {
??this.id = id;
?}
?public String getLoginIp() {
??return loginIp;
?}
?public void setLoginIp(String loginIp) {
??this.loginIp = loginIp;
?}
?public User getLoginUser() {
??return loginUser;
?}
?public void setLoginUser(User loginUser) {
??this.loginUser =loginUser;
?}
?
?public Object clone() {
??Login login=null;
??try {
???login =(Login) super.clone();
??} catch(CloneNotSupportedException e) {
???// TODOAuto-generated catch block
???e.printStackTrace();
??}
??return login;
?}
}
测试一:public class Test {
?public static void main(String[] args) {
??Login loginA=new Login();
??loginA.setId(1000);
??User user = new User();
??user.setId(2000);
??loginA.setLoginUser(user);
??
??Login loginB=loginA;
??loginB.setId(1050);
??loginB.getLoginUser().setId(2050);
??
??System.out.println("loginAid:"+loginA.getId());
??System.out.println("userid:"+user.getId());
?}
}
输出结果:loginA id:1050
????????user id:2050?测试二:将Test类中的Login loginB=loginA;??????????????改成:LoginloginB=(Login) loginA.clone();输出结果:loginA id:1000
?????????userid:2050
由这两个测试,可以看出,使用clone()赋值,与直接赋值的区别,在这里,可以看出Login中的User类的值,无论是使用clone()赋值还是使用直接赋值,它里面的值都会随着LoginB的改变而改变,但改变LoginB其它内容的时候,LoginA中却不会产生变化,这种情况叫做浅度克隆????浅度克隆只会将基础数据类型克隆出来,而深层的对像则不会被克隆出来;????内存图如下:

注:使用浅度克隆的类除了要重写Object类中的Clone()方法,还必须要实现Cloneable接口,才可以合法地对该类实例进行按字段复制。?为了解决类中类不能被克隆的情况:所以产生了深度克隆将创建Login类更改成如下:?import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;public class Login implements Serializable {
?
?private int id;
?private String loginIp;
?private User loginUser;
?
?public int getId() {
??return id;
?}
?public void setId(int id) {
??this.id = id;
?}
?public String getLoginIp() {
??return loginIp;
?}
?public void setLoginIp(String loginIp) {
??this.loginIp = loginIp;
?}
?public User getLoginUser() {
??return loginUser;
?}
?public void setLoginUser(User loginUser) {
??this.loginUser =loginUser;
?}
?
?public Login clone(Login login) {
??Login newLogin=null;
?? ByteArrayInputStream bin =null;??
????????ByteArrayOutputStream bout =null;??
????????try {??
????????????//把对象对到内存中去??
????????????bout = newByteArrayOutputStream();??
????????????ObjectOutputStream oos = newObjectOutputStream(bout);??
????????????oos.writeObject(login);??
????????????oos.close();??
????????????//把对象从内存中读出来????????????
????????????ByteArrayInputStream bais = newByteArrayInputStream(bout.toByteArray());??
????????????ObjectInputStream ois = newObjectInputStream(bais);??
????????????newLogin = (Login)ois.readObject();??
????????????ois.close();??
????????} catch (IOException e) {??
????????????// TODO Auto-generated catchblock??
????????????e.printStackTrace();??
????????} catch (ClassNotFoundException e){??
????????????// TODO Auto-generated catchblock??
????????????e.printStackTrace();??
????????}????return newLogin;
?}
?
}??同时User类也要实现Serializable 接口,目的是标识可序列化?测试三:将Test类中的:Login loginB=(Login) loginA.clone();?????????????改为:?Login loginB=new Login().clone(loginA);?测试结果:loginA id:1000
????????user id:2000?由此可以看出,loginB类中的任何值改变了,原赋值中的类的值是不会跟着改变的内存变化: