Java中的Cloneable接口下的clone深拷贝,单纯的获取那个时刻的值

本文介绍了在 Java 中如何使用 clone 方法来解决对象赋值时的问题,避免因修改一个对象而导致另一个对象的状态变化。通过实例演示了如何实现 Cloneable 接口并重写 clone 方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.背景

         用java写程序的时候很苦恼的一件事就是,如果将一个对象a赋给另一个对象b,那么你改变a的变量值得时候,b的值也对应的变化。如果我们只想单纯的获取那个时刻的a的状况给b的话,就要用到clone方法了。

比如说如下代码:

[java]  view plain  copy
  1. public class Main {  
  2.    
  3.     public static void main(String[] args) {  
  4.         // TODO Auto-generated method stub  
  5.         
  6.        Node n=new Node();  
  7.        Node n1=n;  
  8.         
  9.        n.a=5;  
  10.        
  11.        System.out.print(""+n1.a);  
  12.           
  13.     }  
  14.   
  15. }  
  16. public class Node {  
  17.     int a=1;  
  18.       
  19. }  

输出结果是5,

下面就利用clone实现如上情况输出结果是1.


2.代码

克隆的实现需要一下几步:

在派生类中覆盖基类的clone()方法,并声明为public。

在派生类的clone()方法中,调用super.clone()。

在派生类中实现Cloneable接口。Cloneable接口没有任何抽象的方法,这样的成为标识接口。实现这个接口,只是为了告诉编译器这个对象可以被克隆了。

首先我们在派生类中覆盖了Object类的Clone()方法,并声明为public的。然后我们调用了super.clone()方法,这里会抛出一个异常(对于这个异常大家可以自己查看java的帮助文档),所以必须用try……catch……语句捕获,然后返回此对象。这里需要说明一下,Clone()方法返回的是Object类型的,所以需要强制类型转换

[java]  view plain  copy
  1. public class Main {  
  2.    
  3.     public static void main(String[] args) {  
  4.         // TODO Auto-generated method stub  
  5.         
  6.        Node n=new Node();  
  7.        Node n1=(Node)n.clone();  
  8.         
  9.        n.a=5;  
  10.        
  11.        System.out.print(""+n1.a);  
  12.           
  13.     }  
  14.   
  15. }  
  16. public class Node implements Cloneable{  
  17.     int a=1;  
  18.     public Object clone(){  
  19.         Node n=null;  
  20.             try{  
  21.                   n=(Node)super.clone();  
  22.             }  
  23.             catch(Exception e ){  
  24.                 e.printStackTrace();  
  25.             }  
  26.        return n;  
  27.     }  
  28. }  

输出结果是1;


ps:补充一道题

15. 不通过构造函数也能创建对象吗()

A 是     B 否

答案:A

解析:Java创建对象的几种方式(重要):

(1) 用new语句创建对象,这是最常见的创建对象的方法。
(2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
(3) 调用对象的clone()方法。
(4) 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。

(1)和(2)都会明确的显式的调用构造函数 ;(3)是在内存上对已有对象的影印,所以不会调用构造函数 ;(4)是从文件中还原类的对象,也不会调用构造函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值