千家信息网

Java克隆对象的特性是什么

发表于:2025-11-17 作者:千家信息网编辑
千家信息网最后更新 2025年11月17日,本篇内容介绍了"Java克隆对象的特性是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在java
千家信息网最后更新 2025年11月17日Java克隆对象的特性是什么

本篇内容介绍了"Java克隆对象的特性是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

java面向对象的编程当中,要复制引用类型的对象,就必须克隆对象。通过调用对所有引用类型和对象都是可用的clone方法,来实现克隆。

在Java中传值及引伸深度克隆的思考中,我们讲过引申到克隆技术Java中的所有对象都是Object类的子类。我们知道,Java是纯面向对象的程序设计语言。Java里,所有的类的***父类都是java.lang.Object类,也就是说,如果一个类没有显示 申明继承关系,它的父类默认就是java.lang.Object。

有一个很简单的方法可以证明这一点,我们写一个Test类,如下:

public class Test {   public void someMethod() {   super.clone();   }   }

里面调用了super.clone(),编译时并不报错。其实clone()方法为java.lang.Object类提供的一个 protected型方法。

对象克隆

本文通过介绍java.lang.Object#clone()方法来说明Java语言的对象克隆特性。

java.lang.Object#clone()方法由java.lang.Object加以实现,主要对对象本身加以克隆。

首先我们看看下面的例子:

public class TestClone {   public static void main(String[] args) {   MyClone myClone1 = new MyClone("clone1");   MyClone myClone2 = (MyClone)myClone1.clone();   if (myClone2 != null) {   System.out.println(myClone2.getName());  System.out.println("myClone2 equals myClone1: " + myClone2.equals(myClone1));   } else {   System.out.println("Clone Not Supported");   }   } }   class MyClone {   private String name;   public MyClone(String name) {   this.name = name;   }  public String getName() {   return name;   }   public void setName(String name) {   this.name = name; }  public Object clone() {   try {  return super.clone();   } catch (CloneNotSupportedException e) {   return null;   }}

编译执行TestClone,打印出:

C:\clone>javac *.java   C:\clone>java TestClone   Clone Not Supported   C:\clone>

说明MyClone#clone()方法调用super.clone()时抛出了CloneNotSupportedException异常,不支持克隆。

为什么父类java.lang.Object里提供了clone()方法,却不能调用呢?

原来,Java语言虽然提供了这个方法,但考虑到安全问题, 一方面将clone()访问级别设置为protected型,以限制外部类访问;

另一方面,强制需要提供clone功能的子类实现java.lang.Cloneable接口,在运行期,JVM会检查调用clone()方法的 类,如果该类未实现java.lang.Cloneable接口,则抛出CloneNotSupportedException异常。

java.lang.Cloneable接口是一个空的接口,没有申明任何属性与方法。该接口只是告诉JVM,该接口的实现类需要开放"克隆"功能。

我们再将MyClone类稍作改变,让其实现Cloneable接口:

class MyClone implements Cloneable {   ...//其余不做改变   }   编译执行TestClone,打印出:   C:\clone>javac *.java   C:\clone>java TestClone   clone1   myClone2 equals myClone1: false   C:\clone>

根据结果,我们可以发现:

1,myClone1.clone()克隆了跟myClone1具有相同属性值的对象

2,但克隆出的对象myClone2跟myClone1不是同一个对象(具有不同的内存空间)

小结

如果要让一个类A提供克隆功能,该类必须实现java.lang.Cloneable接口,并重载 java.lang.Object#clone()方法。

public class A extends Cloneable {   public Object clone() {   try {   return super.clone();   } catch (CloneNotSupportedException e) {   //throw (new InternalError(e.getMessage()));   return null;   }   }   }

对象的深层次克隆

上例说明了怎么样克隆一个具有简单属性(String,int,boolean等)的对象。

但如果一个对象的属性类型是List,Map,或者用户自定义的其他类时,克隆行为是通过怎样的方式进行的?

很多时候,我们希望即使修改了克隆后的对象的属性值,也不会影响到原对象,这种克隆我们称之为对象的深层次克隆。怎么样实现对象的深层次克隆呢?

验证对象的克隆方式

为了验证对象的克隆方式,我们对上面的例子加以改进,如下(为了节省篇幅,我们省略了setter与getter方法):

public class TestClone {   public static void main(String[] args) {   //为克隆对象设置值   MyClone myClone1 = new MyClone("clone1");   myClone1.setBoolValue(true);   myClone1.setIntValue(100);   //设置List值   List listValue = new ArrayList();   listValue.add(new Element("ListElement1"));   listValue.add(new Element("ListElement2"));   listValue.add(new Element("ListElement3"));   myClone1.setListValue(listValue);   //设置Element值   Element element1 = new Element("element1");   myClone1.setElement(element1);   //克隆   MyClone myClone2 = (MyClone)myClone1.clone();   if (myClone2 != null) {   //简单属性   System.out.println("myClone2.name=" + myClone2.getName()   + " myClone2.boolValue=" + myClone2.isBoolValue()   + " myClone2.intValue=" + myClone2.getIntValue() );   //复合属性(List与Element)   List clonedList = myClone2.getListValue();   Element element2 = myClone2.getElement();   System.out.println("myClone2.listValue.size():" + clonedList.size());   System.out.println("myClone2.element.equals(myClone1.element):" + element2.equals(element1));   System.out.println("myClone2.element.name:" + element2.getName());  //下面我们测试一下myClone2.element是否等于myClone1.element   //以及myClone2.listValue是否等于myClone1.listValue   //为此,我们修改myClone2.element与myClone2.listValue,如果myClone1的相应值也跟着被修改了,则它们引用 的是同一个内存空间的变量,我们认为它们相等   clonedList.add("ListElement4");   System.out.println("myClone1.listValue.size():" + listValue.size());   element2.setName("Element2");   System.out.println("myClone1.element.name:" + element1.getName());   } else {   System.out.println("Clone Not Supported");   }   }   }   class MyClone implements Cloneable {   private int intValue;   private boolean boolValue;   private String name;   private List listValue;   private Element element;   public MyClone(String name) {   this.name = name;   }  ...//setter与getter方法(略)   }   class Element implements Cloneable {   private String name;   public Element (String name) {   this.name = name;   }   ...//setter与getter方法(略)   }

编译执行TestClone,打印出:

C:\clone>javac *.java   C:\clone>java TestClone   myClone2.name=clone1 myClone2.boolValue=true myClone2.intValue=100   myClone2.listValue.size():3   myClone2.element.equals(myClone1.element):true   myClone2.element.name:element1   myClone1.listValue.size():4   myClone1.element.name:Element2 09.myClone2 equals myClone1: false 10.C:\clone> 11.

我们发现,对于对象里的List,Element等复合属性,super.clone()只是简单地赋值,没有采取克隆手段。也就是说,修改被克 隆后的对象值,会影响到原对象。

怎么进行深层次的克隆呢?

答案是,我们只能手动在重载的clone()方法里,对属性也分别采用克隆操作。当然条件是,属性类也得支持克隆操作

class MyClone implements Cloneable {   ...   public Object clone() {   try {   MyClone myClone = (MyClone)super.clone();   //分别对属性加以克隆操作   myClone.element = this.element.clone();   myClone.listValue = new ArrayList();   for (Element ele:this.listValue) {   myClone.listValue.add(ele.clone());   }   return myClone;   } catch (CloneNotSupportedException e) {   return null;   }   }   ...  }   //让Element类也支持克隆操作   class Element implements Cloneable {   ...   public Element clone() {   try {   return (Element)super.clone();   } catch (CloneNotSupportedException e) {   return null;   }   }   }

深层次的克隆操作往往存在效率问题,尤其是需要让List,Map等集合类也支持深层次的克隆操作时。

"Java克隆对象的特性是什么"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

对象 方法 属性 接口 深层 支持 编译 特性 功能 方式 类型 语言 也就是 也就是说 例子 内存 内容 只是 子类 更多 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 access数据库干嘛的 科技信息公司互联网金融 网络安全法需绑定手机号 服务器搭建版本管理器 住建软件开发 尤优科技是互联网公司么 决策中国影响力人物数据库李秀凤 国家湿地公园数据库 更改邮件收发服务器信息 打开设备管理器找不到服务器 unity如何调用服务器资源 家里搭建服务器网速会快一点吗 智斓软件开发有限公司 西安物流软件开发收费多少 怎么看数据库保留多久的数据 信息安全党课网络安全日 网络安全龙头三六零 江苏网络技术服务厂家报价 和平精英最新更新怎么换服务器 广东手机软件开发设计 如何附加数据库备份文件 中国知网数据库检索实践要求 学软件开发有什么好技校 互联网美食科技 软件开发人月收费 嵌入式软件开发模式 h3c服务器装ubuntu 怎么看数据库保留多久的数据 斑马网络技术有限公司的股权 辅导员提高网络安全意识
0