拷贝用到Object对象的clone()方法,但该类必须直接或间接实现 Cloneable接口,
如果在没有实现 Cloneable 接口的实例上调用 Object 的 clone 方法,则会导致抛出 CloneNotSupportedException 异常。
一、浅拷贝
实现基本数据类型的拷贝(包括基本数据类型的包装类),而不能实现引用类型的拷贝
例子一:
package Test;
public class Test extends Object {
public static void main(String[] args) throws Exception {
Dog dog = new Dog("小白",10);
Dog clonedDog = (Dog)dog.clone();// 拷贝一个新的Dog
System.out.println("打印被拷贝Dog的属性:");
System.out.println(dog.getName());
System.out.println(dog.getAge());
System.out.println(dog.getFriend().getName()+ ";" + dog.getFriend().getAge());
System.out.println("打印拷贝Dog的属性:");
System.out.println(clonedDog.getName());
System.out.println(clonedDog.getAge());
// 修改拷贝Dog的属性
clonedDog.setName("喵喵");
clonedDog.setAge(20);
clonedDog.getFriend().setName("黑猫");
clonedDog.getFriend().setAge(20);
System.out.println("修改之后,打印被拷贝Dog的属性:");
System.out.println(dog.getName());
System.out.println(dog.getAge());
System.out.println(dog.getFriend().getName()+ ";" + dog.getFriend().getAge());
System.out.println("修改之后,打印拷贝Dog的属性:");
System.out.println(clonedDog.getAge());
System.out.println(clonedDog.getName());
System.out.println(clonedDog.getFriend().getName() + ";" + clonedDog.getFriend().getAge());
System.out.println("输出两个对象中friend的hashCode:");
System.out.println( dog.getFriend().hashCode() + "--" + clonedDog.getFriend().hashCode());
}
}
/**
* 声明一个Dog类,并实现Cloneable接口来支持clone方法
* @author 李洋
*
*/
class Dog implements Cloneable{
private Integer age;// Dog的年龄
private String name;// Dog的名字
private Cat friend; // Dog的朋友
public Dog(String name,Integer age)
{
this.name = name;
this.age = age;
friend = new Cat("加菲猫",12);
}
// 调用父类的clone
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
// 属性的set get方法
public Integer getAge(){
return age;
}
public void setAge(Integer age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setFriend(Cat cat){
this.friend = cat;
}
public Cat getFriend(){
return this.friend;
}
}
class Cat implements Cloneable{
private String name;// 猫的名字
private Integer age;// 猫的年龄
public Cat(String name,Integer age){
this.name = name;
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
// 属性的set、get方法
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(Integer age){
this.age = age;
}
public Integer getAge(){
return this.age;
}
}
二、深拷贝
既要实现基本数据类型的拷贝,也要实现引用类型的拷贝。
实现例子一深拷贝的第一种方法:
package Test;
public class Test extends Object {
public static void main(String[] args) throws Exception {
Dog dog = new Dog("小白",10);
Dog clonedDog = (Dog)dog.clone();// 拷贝一个新的Dog
// 这句可以实现深拷贝
clonedDog.setFriend((Cat)dog.getFriend().clone());
System.out.println("打印被拷贝Dog的属性:");
System.out.println(dog.getName());
System.out.println(dog.getAge());
System.out.println(dog.getFriend().getName()+ ";" + dog.getFriend().getAge());
System.out.println("打印拷贝Dog的属性:");
System.out.println(clonedDog.getName());
System.out.println(clonedDog.getAge());
// 修改拷贝Dog的属性
clonedDog.setName("喵喵");
clonedDog.setAge(20);
clonedDog.getFriend().setName("黑猫");
clonedDog.getFriend().setAge(20);
System.out.println("修改之后,打印被拷贝Dog的属性:");
System.out.println(dog.getName());
System.out.println(dog.getAge());
System.out.println(dog.getFriend().getName()+ ";" + dog.getFriend().getAge());
System.out.println("修改之后,打印拷贝Dog的属性:");
System.out.println(clonedDog.getAge());
System.out.println(clonedDog.getName());
System.out.println(clonedDog.getFriend().getName() + ";" + clonedDog.getFriend().getAge());
System.out.println("输出两个对象中friend的hashCode:");
System.out.println( dog.getFriend().hashCode() + "--" + clonedDog.getFriend().hashCode());
}
}
/**
* 声明一个Dog类,并实现Cloneable接口来支持clone方法
* @author 李洋
*
*/
class Dog implements Cloneable{
private Integer age;// Dog的年龄
private String name;// Dog的名字
private Cat friend; // Dog的朋友
public Dog(String name,Integer age)
{
this.name = name;
this.age = age;
friend = new Cat("加菲猫",12);
}
// 调用父类的clone
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
// 属性的set get方法
public Integer getAge(){
return age;
}
public void setAge(Integer age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setFriend(Cat cat){
this.friend = cat;
}
public Cat getFriend(){
return this.friend;
}
}
class Cat implements Cloneable{
private String name;// 猫的名字
private Integer age;// 猫的年龄
public Cat(String name,Integer age){
this.name = name;
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
// 属性的set、get方法
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(Integer age){
this.age = age;
}
public Integer getAge(){
return this.age;
}
}
实现例子一深拷贝的第二种方法:
package Test;
public class Test extends Object {
public static void main(String[] args) throws Exception {
Dog dog = new Dog("小白",10);
Dog clonedDog = (Dog)dog.clone();// 拷贝一个新的Dog
System.out.println("打印被拷贝Dog的属性:");
System.out.println(dog.getName());
System.out.println(dog.getAge());
System.out.println(dog.getFriend().getName()+ ";" + dog.getFriend().getAge());
System.out.println("打印拷贝Dog的属性:");
System.out.println(clonedDog.getName());
System.out.println(clonedDog.getAge());
// 修改拷贝Dog的属性
clonedDog.setName("喵喵");
clonedDog.setAge(20);
clonedDog.getFriend().setName("黑猫");
clonedDog.getFriend().setAge(20);
System.out.println("修改之后,打印被拷贝Dog的属性:");
System.out.println(dog.getName());
System.out.println(dog.getAge());
System.out.println(dog.getFriend().getName()+ ";" + dog.getFriend().getAge());
System.out.println("修改之后,打印拷贝Dog的属性:");
System.out.println(clonedDog.getAge());
System.out.println(clonedDog.getName());
System.out.println(clonedDog.getFriend().getName() + ";" + clonedDog.getFriend().getAge());
System.out.println("输出两个对象中friend的hashCode:");
System.out.println( dog.getFriend().hashCode() + "--" + clonedDog.getFriend().hashCode());
}
}
/**
* 声明一个Dog类,并实现Cloneable接口来支持clone方法
* @author 李洋
*
*/
class Dog implements Cloneable{
private Integer age;// Dog的年龄
private String name;// Dog的名字
private Cat friend; // Dog的朋友
public Dog(String name,Integer age)
{
this.name = name;
this.age = age;
friend = new Cat("加菲猫",12);
}
// 在这里实现深拷贝
public Object clone() throws CloneNotSupportedException {
Dog cloneDog = new Dog(this.name,this.age);
cloneDog.setFriend(new Cat(this.getFriend().getName(),this.getFriend().getAge()));
return cloneDog;
}
// 属性的set get方法
public Integer getAge(){
return age;
}
public void setAge(Integer age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setFriend(Cat cat){
this.friend = cat;
}
public Cat getFriend(){
return this.friend;
}
}
class Cat implements Cloneable{
private String name;// 猫的名字
private Integer age;// 猫的年龄
public Cat(String name,Integer age){
this.name = name;
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
// 属性的set、get方法
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(Integer age){
this.age = age;
}
public Integer getAge(){
return this.age;
}
}