之前一直听说相关的内容,但是一直没有时间总结,
今天就挤出一点时间来总结一下,然后加深一下自己的印象。
首先来一个直接赋值:
package test1;
import lombok.Data;
/**
*
* @ClassName CopyTest
* @author yaxuSong
* @date 2017年8月28日 上午10:47:32
* @Description TODO
*/
@Data
class Student{
private User user;
private String stuNo;
/**
* @return the user
*/
public User getUser() {
return user;
}
/**
* @param user the user to set
*/
public void setUser(User user) {
this.user = user;
}
/**
* @return the stuNo
*/
public String getStuNo() {
return stuNo;
}
/**
* @param stuNo the stuNo to set
*/
public void setStuNo(String stuNo) {
this.stuNo = stuNo;
}
public Student(int id,String name,String stuNo){
this.user = new User(id,name);
this.stuNo=stuNo;
}
}
@Data
class User{
private String name;
private int id;
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}
public User(int id,String name){
this.id=id;
this.name=name;
}
}
public class CopyTest {
public static void main(String[] args){
System.out.println("1.直接赋值:--------------------------------");
Student st1 = new Student(1,"张三","00001");
Student st2 = new Student(2,"李四","00002");
System.out.println(st1.toString());
System.out.println(st2.toString());
st1 = st2;
System.out.println("赋值之后");
System.out.println(st1.toString());
System.out.println(st2.toString());
System.out.print("st1==st2 ? :->");
System.out.println(st1==st2);
System.out.println("-------------------------------------------");
}
}
输出结果:
1.直接赋值:--------------------------------
Student(user=User(name=张三, id=1), stuNo=00001)
Student(user=User(name=李四, id=2), stuNo=00002)
赋值之后
Student(user=User(name=李四, id=2), stuNo=00002)
Student(user=User(name=李四, id=2), stuNo=00002)
st1==st2 ? :->true
-------------------------------------------
然后我们发现 赋值之后的st1竟然和st2是相等的。
这就是直接赋值,是st1的对象引用指向了st2的对象引用。
然后稍微修改一下代码,来一个浅拷贝:
package test1;
import lombok.Data;
/**
*
* @ClassName CopyTest
* @author yaxuSong
* @date 2017年8月28日 上午10:47:32
* @Description TODO
*/
@Data
class Student implements Cloneable{
private User user;
private String stuNo;
/**
* @return the user
*/
public User getUser() {
return user;
}
/**
* @param user the user to set
*/
public void setUser(User user) {
this.user = user;
}
/**
* @return the stuNo
*/
public String getStuNo() {
return stuNo;
}
/**
* @param stuNo the stuNo to set
*/
public void setStuNo(String stuNo) {
this.stuNo = stuNo;
}
public Student(int id,String name,String stuNo){
this.user = new User(id,name);
this.stuNo=stuNo;
}
@Override
public Object clone() {
Student stu = null;
try{
stu = (Student)super.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return stu;
}
}
@Data
class User{
private String name;
private int id;
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}
public User(int id,String name){
this.id=id;
this.name=name;
}
}
public class CopyTest {
public static void main(String[] args){
System.out.println("2.浅拷贝:--------------------------------");
Student st1 = new Student(1,"张三","00001");
Student st2 = new Student(2,"李四","00002");
System.out.println(st1.toString());
System.out.println(st2.toString());
st1 = (Student)st2.clone();
System.out.println("赋值之后");
System.out.println(st1.toString());
System.out.println(st2.toString());
System.out.print("st==st2 ? :->");
System.out.println(st1==st2);
System.out.println(st1.getUser()==(st2.getUser()));
System.out.println("-------------------------------------------");
}
}
输出结果:
2.浅拷贝:--------------------------------
false
Student(user=User(name=张三, id=1), stuNo=00001)
Student(user=User(name=李四, id=2), stuNo=00002)
赋值之后
Student(user=User(name=李四, id=2), stuNo=00002)
Student(user=User(name=李四, id=2), stuNo=00002)
st==st2 ? :->false
true
-------------------------------------------
我们可以看到,虽然st1和st2进行了赋值,但是赋值之后不再是相等了。
但是user部分还是相等的。
我们再修改下代码,然后测试3.深拷贝:
package test1;
import lombok.Data;
/**
*
* @ClassName CopyTest
* @author yaxuSong
* @date 2017年8月28日 上午10:47:32
* @Description TODO
*/
@Data
class Student implements Cloneable{
private User user;
private String stuNo;
/**
* @return the user
*/
public User getUser() {
return user;
}
/**
* @param user the user to set
*/
public void setUser(User user) {
this.user = user;
}
/**
* @return the stuNo
*/
public String getStuNo() {
return stuNo;
}
/**
* @param stuNo the stuNo to set
*/
public void setStuNo(String stuNo) {
this.stuNo = stuNo;
}
public Student(int id,String name,String stuNo){
this.user = new User(id,name);
this.stuNo=stuNo;
}
@Override
public Object clone() {
Student stu = null;
try{
stu = (Student)super.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
stu.user = (User)user.clone();
return stu;
}
}
@Data
class User implements Cloneable{
private String name;
private int id;
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}
public User(int id,String name){
this.id=id;
this.name=name;
}
@Override
public Object clone() {
User u = null;
try{
u = (User)super.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return u;
}
}
public class CopyTest {
public static void main(String[] args){
System.out.println("3.深拷贝:--------------------------------");
Student st1 = new Student(1,"张三","00001");
Student st2 = new Student(2,"李四","00002");
System.out.println(st1.toString());
System.out.println(st2.toString());
st1 = (Student)st2.clone();
System.out.println("赋值之后");
System.out.println(st1.toString());
System.out.println(st2.toString());
System.out.print("st==st2 ? :->");
System.out.println(st1==st2);
System.out.println(st1.getUser()==(st2.getUser()));
System.out.println("-------------------------------------------");
}
}
输出结果:
3.深拷贝:--------------------------------
Student(user=User(name=张三, id=1), stuNo=00001)
Student(user=User(name=李四, id=2), stuNo=00002)
赋值之后
Student(user=User(name=李四, id=2), stuNo=00002)
Student(user=User(name=李四, id=2), stuNo=00002)
st==st2 ? :->false
false
-------------------------------------------
我们看到现在所有的都是不相等的。
代码的区别在于是否对象内所有的引用也进行了copy,而不是进行简单的赋值。