电脑技术学习

Java的浅拷贝和深拷贝(1)

dn001
java的拷贝分为深拷贝和浅拷贝

浅拷贝:把一个对象中所有的非static成员变量(包括对其它对象的引用,java中的引用相当于C/C++中的指针变量)都拷贝一遍,而不拷贝引用所指向的对象

深拷贝:把一个对象中所有的非static成员变量(包括对其它对象的引用)都拷贝一遍,引用所指向的对象也拷贝一份

这篇文章先讲述浅拷贝,深拷贝下篇文章讲述

一个类的对象如果想要具有拷贝的功能,比如符号如下条件:

1.必须实现Cloneable接口(这个接口中没有定义方法,叫做标记接口)

2.重写Object类的clone()方法,该方法实现的是浅拷贝

3.在该类的clone()方法中的第一句,比如调用super.clone()来调用Object的clone()方法来实现拷贝

以下是一个浅拷贝的例子:

view plaincopy to clipboardPRint?
package com.test;;;;
public class CloneTest;;;
{;;;
public static void main(String[] args);;;
{;;;
Student s1 = new Student();;;;
s1.setAge(20);;;;
s1.setName("wudi");;;;
School school = new School();;;;
school.setName("Peiyang University");;;;
school.setBornYear(1895);;;;
s1.setSchool(school);;;;
System.out;;;
.println("s1:" + s1.getName() + " " + s1.getAge() + " ";;
+ s1.getSchool().getName() + " ";;
+ s1.getSchool().getBornYear());;;;

try;;
{;;;
//拷贝一个学生;;;
Student s2 = (Student)s1.clone();;;;
s2.setAge(21);;;;
s2.setName("WUDI");;;;
System.out;;;
.println("s2:" + s2.getName() + " " + s2.getAge() + " ";;
+ s2.getSchool().getName() + " ";;
+ s2.getSchool().getBornYear());;;;

System.out.println("after s2 changing some property:");;;;
//通过学生s2改变了他所在学校的名称和成立时间;;;
s2.getSchool().setName("Tianjin University");;;;
s2.getSchool().setBornYear(1951);;;;


System.out;;;
.println("s1:" + s1.getName() + " " + s1.getAge() + " ";;
+ s1.getSchool().getName() + " ";;
+ s1.getSchool().getBornYear());;;;
System.out;;;
.println("s2:" + s2.getName() + " " + s2.getAge() + " ";;
+ s2.getSchool().getName() + " ";;
+ s2.getSchool().getBornYear());;;;




};;;;
catch (CloneNotSupportedException e);;;
{;;;
e.printStackTrace();;;;
};;;
};;;
};;;
class School;;;
{;;;
private String name;;;;
private int bornYear;;;;
public String getName();;;
{;;;
return name;;;;
};;;
public void setName(String name);;;
{;;;
this.name = name;;;;
};;;
public int getBornYear();;;
{;;;
return bornYear;;;;
};;;
public void setBornYear(int bornYear);;;
{;;;
this.bornYear = bornYear;;;;
};;;
};;;
class Student implements Cloneable;;;
{;;;
private int age;;;;
private String name;;;;
private School school;;;;
public School getSchool();;;
{;;;
return school;;;;
};;;
public void setSchool(School school);;;
{;;;
this.school = school;;;;
};;;
public int getAge();;;
{;;;
return age;;;;
};;;
public void setAge(int age);;;
{;;;
this.age = age;;;;
};;;
public String getName();;;
{;;;
return name;;;;
};;;
public void setName(String name);;;
{;;;
this.name = name;;;;
};;;
@Override;;
protected Object clone() throws CloneNotSupportedException;;;
{;;;
return super.clone();;;;
};;;
};;;
package com.test;
public class CloneTest
{
public static void main(String[] args)
{
Student s1 = new Student();
s1.setAge(20);
s1.setName("wudi");
School school = new School();
school.setName("Peiyang University");
school.setBornYear(1895);
s1.setSchool(school);
System.out
.println("s1:" + s1.getName() + " " + s1.getAge() + " "
+ s1.getSchool().getName() + " "
+ s1.getSchool().getBornYear());

try
{
//拷贝一个学生
Student s2 = (Student)s1.clone();
s2.setAge(21);
s2.setName("WUDI");
System.out
.println("s2:" + s2.getName() + " " + s2.getAge() + " "
+ s2.getSchool().getName() + " "
+ s2.getSchool().getBornYear());

System.out.println("after s2 changing some property:");
//通过学生s2改变了他所在学校的名称和成立时间
s2.getSchool().setName("Tianjin University");
s2.getSchool().setBornYear(1951);


System.out
.println("s1:" + s1.getName() + " " + s1.getAge() + " "
+ s1.getSchool().getName() + " "
+ s1.getSchool().getBornYear());
System.out
.println("s2:" + s2.getName() + " " + s2.getAge() + " "
+ s2.getSchool().getName() + " "
+ s2.getSchool().getBornYear());




}
catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
}
}
class School
{
private String name;
private int bornYear;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getBornYear()
{
return bornYear;
}
public void setBornYear(int bornYear)
{
this.bornYear = bornYear;
}
}
class Student implements Cloneable
{
private int age;
private String name;
private School school;
public School getSchool()
{
return school;
}
public void setSchool(School school)
{
this.school = school;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException
{
return super.clone();
}
};;

从运行结果可以看出,通过学生s2将其引用school所指向的对象的name和bornYear属性改变,相应的s1的也被改变,这说明学生s1和学生s2里面的school引用指向的始终是同一个School对象。这就是浅拷贝的含义。