java为什么要 对象克隆:

在程序开发时,有时可能会遇到以下情况:已经存在一个对象A,现在需要一个与A对象完全相同的B 对象,并对B 对象的属性值进行修改,但是A 对象原有的属性值不能改变。这时,如果使用Java 提供的对象赋值语句,当修改B 对象的属性值后,A 对象的属性值也将被修改。那么应该如何实现创建一个与A 对象完全相同的B 对象,但是改变B对象的属性值时A 对象的属性值不变呢?

专家解答

要实现这一功能,可以使用Object 类中的clone()方法。clone()方法可以用来完成对象的浅克隆。所谓浅克隆就是说被克隆的对象各个属性都是基本类型,而不是引用类型。如果存在引用类型的属性,则需要进行深克隆。下面对这两种克隆方式进行举例说明。

1.浅克隆(1)编写Address 类,首先在该类中定义state(表示国家)、province(表示省)和city(表示市)3 个域,然后在构造方法中初始化这3 个域,并提供getter()和setter()方法用于获得和修改这3 个域,最后重写toString()方法方便输出该类的对象,代码如下:

1.浅克隆(1)编写Address 类,首先在该类中定义state(表示国家)、province(表示省)和city(表示市)3 个域,然后在构造方法中初始化这3 个域,并提供getter()和setter()方法用于获得和修改这3 个域,最后重写toString()方法方便输出该类的对象,代码如下:

地址对象:

packagecom.nf147.Constroller;public class Address implementsCloneable {private String state; //国家

private String province; //省

private String city; //市

publicAddress() {

}publicAddress(String state, String province, String city) {this.state =state;this.province =province;this.city =city;

}publicString getState() {returnstate;

}public voidsetState(String state) {this.state =state;

}publicString getProvince() {returnprovince;

}public voidsetProvince(String province) {this.province =province;

}publicString getCity() {returncity;

}public voidsetCity(String city) {this.city =city;

}

@Overridepublic String toString() { //重写toString

StringBuilder sb=newStringBuilder();

sb.append("国家:"+state+",");

sb.append("省:"+province+",");

sb.append("市:"+city+",");returnsb.toString();

}

}

编写Employee 类,首先在该类中定义name(表示姓名)、age(表示年龄)和address(表示地址)3 个域,然后在构造方法中初始化这3 个域,并提供getter()和setter()方法用于获得和修改这3 个域,再重写toString()方法方便输出该类的对象,最后重写clone()方法来提供克隆的功能,代码如下:

员工:

packagecom.nf147.Constroller;public class Employee implementsCloneable {private String name; //姓名

private int age; //年龄

private Address address; //地址

public Employee(String name, intage, Address address) {this.name =name;this.age =age;this.address =address;

}publicEmployee() {

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}public intgetAge() {returnage;

}public void setAge(intage) {this.age =age;

}publicAddress getAddress() {returnaddress;

}public voidsetAddress(Address address) {this.address =address;

}

@Overridepublic String toString() { //重新toString()方法

return "Employee{" +

"姓名='" + name + '\'' +

", 年龄=" + age +

", 地址=" + address +

'}';

}public Employee clone() { //实现浅克隆

Employee employee = null;try{

employee= (Employee) super.clone();

employee.address=address.clone();

}catch(CloneNotSupportedException e) {

e.printStackTrace();

}returnemployee;

}

}

测试类:

packagecom.nf147.Constroller;public classTestClone {public static voidmain(String[] args) {

System.out.println("克隆之前:");

Address address= new Address("中国", "吉林", "长春");

Employee employee1= new Employee("无语", 32, address);

System.out.println("员工 1 的信息");

System.out.println(employee1);

System.out.println("====================");

System.out.println("克隆之后:");

Employee employee2=employee1.clone();

employee2.getAddress().setState("中国");

employee2.getAddress().setProvince("辽宁");

employee2.getAddress().setCity("大连");

employee2.setName("倾城");

employee2.setAge(33);

System.out.println("员工2 的 信息");

System.out.println(employee2);

System.out.println("员工1的 信息");

System.out.println(employee1);

}

}

截图:

说明:

从图中可以看到,对于引用类型并没有克隆成功。

2.深克隆(1)编写类Address1,在该类中首先定义state(表示国家)、province(表示省)和city(表示市)3 个域,然后在构造方法中初始化这3 个域,并提供了getter()和setter()方法用于获得和修改这3 个域,再重写toString()方法方便输出该类的对象,最后重写clone()方法提供克隆的功能,关键代码如下:

packagecom.nf147.Constroller;public class Address implementsCloneable {private String state; //国家

private String province; //省

private String city; //市

publicAddress() {

}publicAddress(String state, String province, String city) {this.state =state;this.province =province;this.city =city;

}publicString getState() {returnstate;

}public voidsetState(String state) {this.state =state;

}publicString getProvince() {returnprovince;

}public voidsetProvince(String province) {this.province =province;

}publicString getCity() {returncity;

}public voidsetCity(String city) {this.city =city;

}

@Overridepublic String toString() { //重写toString

StringBuilder sb=newStringBuilder();

sb.append("国家:"+state+",");

sb.append("省:"+province+",");

sb.append("市:"+city+",");returnsb.toString();

}

@OverrideprotectedAddress clone(){

Address address= null;try{

address=(Address)super.clone();

}catch(CloneNotSupportedException e){

e.printStackTrace();

}returnaddress;

}

}

说明:

Address 类的域不是基本类型就是不可变类型,所以可以直接使用浅克隆。

(2)编写Employee类,首先在该类中定义name(表示姓名)、age(表示年龄)和address(表示地址)3 个域,然后在构造方法中初始化这3 个域,并提供getter()和setter()方法用于获得和修改这3 个域,再重写toString()方法方便输出该类的对象,最后重写clone()方法来提供克隆的功能。代码如下:

packagecom.nf147.Constroller;public class Employee implementsCloneable {private String name; //姓名

private int age; //年龄

private Address address; //地址

public Employee(String name, intage, Address address) {this.name =name;this.age =age;this.address =address;

}publicEmployee() {

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}public intgetAge() {returnage;

}public void setAge(intage) {this.age =age;

}publicAddress getAddress() {returnaddress;

}public voidsetAddress(Address address) {this.address =address;

}

@Overridepublic String toString() { //重新toString()方法

return "Employee{" +

"姓名='" + name + '\'' +

", 年龄=" + age +

", 地址=" + address +

'}';

}public Employee clone() { //实现浅克隆

Employee employee = null;try{

employee= (Employee) super.clone();

employee.address=address.clone();

}catch(CloneNotSupportedException e) {

e.printStackTrace();

}returnemployee;

}

}

测试:

packagecom.nf147.Constroller;public classTestClone {public static voidmain(String[] args) {

System.out.println("克隆之前:");

Address address= new Address("中国", "吉林", "长春");

Employee employee1= new Employee("无语", 32, address);

System.out.println("员工 1 的信息");

System.out.println(employee1);

System.out.println("====================");

System.out.println("克隆之后:");

Employee employee2=employee1.clone();

employee2.getAddress().setState("中国");

employee2.getAddress().setProvince("辽宁");

employee2.getAddress().setCity("大连");

employee2.setName("倾城");

employee2.setAge(33);

System.out.println("员工2 的 信息");

System.out.println(employee2);

System.out.println("员工1的 信息");

System.out.println(employee1);

}

}

截图:

java 克隆对象_Java 中如何使用clone()方法克隆对象?相关推荐

  1. java同步关键字_Java中synchronized关键字修饰方法同步的用法详解

    Java的最基本的同步方式,即使用synchronized关键字来控制一个方法的并发访问. 每一个用synchronized关键字声明的方法都是临界区.在Java中,同一个对象的临界区,在同一时间只有 ...

  2. java.equal例子_Java中的== 和equals()方法详解与实例

    Java中的== 和equals()方法: Java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型. byte,short,char,int,long,float,double,boo ...

  3. java 释放一个对象_JAVA中销毁一个对象的方法

    方法一:垃圾回收器 垃圾回收器是Java平台中用的最频繁的一种对象销毁方法.垃圾回收器会全程侦测Java应用程序的运行情况.当反先有些对象成为垃圾时,垃圾回收器就会销毁这些对象,并释放这些对象所占用的 ...

  4. java如何重写_java中如何重写一个方法

    方法的重写: 1.在子类中可以根据需要对从基类中继承来的方法进行重写. 2.重写的方法和被重写的方法必须具有相同方法名称.参数列表和返回类型. 3.重写方法不能使用比被重写的方法更严格的访问权限. 在 ...

  5. java wait 参数_java中wait()和join()方法的区别是什么

    java中wait()和join()方法的区别是:存在不同的java包中:wait()方法用于线程间通信,它所施加的等待状态的线程可以被启动:join()方法用于在多个线程之间添加排序,它所施加的等待 ...

  6. java 结束循环_java中结束循环的方法

    java中结束循环的方法 发布时间:2020-06-25 11:31:06 来源:亿速云 阅读:180 作者:Leah 这篇文章将为大家详细讲解有关java中结束循环的方法,小编觉得挺实用的,因此分享 ...

  7. java listfiles 使用_Java中list()和listFiles()方法之间的区别

    java.io包的名为File的类表示系统中的文件或目录(路径名).为了获得目录中所有现有文件的列表,此类提供了list()和ListFiles()方法. 它们之间的主要区别是该列表()方法返回一个字 ...

  8. java map大小_Java中HashMap的size()方法: HashMap.size() - Break易站

    Java中的HashMap HashMap类的java.util.HashMap.size()方法用于获取哈希映射HashMap中映射的大小,该映射引用Map中键值对或映射的数量. 句法: Hash_ ...

  9. java securerandom使用_Java中的SecureRandom nextBytes()方法

    用户指定的随机字节数可以使用nextBytes()类java.security.SecureRandom中的方法获得.该方法需要一个参数,即一个随机字节数组,它返回用户指定的随机字节. 演示此的程序如 ...

最新文章

  1. linux系统目录树/内核源码目录树
  2. 数学之美笔记(十三)
  3. [leetcode] 912.排序数组
  4. 计算机公共基础知识实验报告,20140902413 李雪瑞 计算机工程系实验报告345.docx...
  5. python for循环例子_Python for循环生成列表的实例
  6. 走进AngularJs(七) 过滤器(filter) - 吕大豹
  7. Rize - 一个可以让你简单、优雅地使用 puppeteer 的 Node.js 库
  8. stm32的HAL库uart的注意点
  9. 深入理解JVM虚拟机(一):JVM运行时数据区
  10. 手把手教你Excel数据处理!
  11. 规则引擎Drools使用 第十一篇 Drools 的高级语法之LHS增强
  12. Linux系统(三)系统基础扫盲大全
  13. 《马丁伊登》读后感范文(下)2000字
  14. Android机型适配
  15. 用Go建千亿级微服务 分析详细,适合新手理解概念
  16. 程序员的奋斗史(二十八)——寒门再难出贵子
  17. 12pm 是中午12点 还是晚上12点 ??
  18. Visual Studio 2015 提示安装包损坏或丢失
  19. linux 板卡驱动开源项目Comedi使用编译流程
  20. 基于DDD的现代ASP.NET开发框架--ABP系列文章总目录(转)

热门文章

  1. [转帖]3万公里东风标致206机油试用心得
  2. java接口通信协议_常见通信协议
  3. Wireshark的常见提示
  4. 【嵌入式系统】基于触摸屏控制的多功能电子钟
  5. 互联网大厂薪酬2021版新鲜出炉!含阿里、腾讯、字节跳动...
  6. random.uniform()总结
  7. MFS分布式存储 心得体会
  8. supercard游戏系统开发
  9. 【Python 百练成钢】灯光模拟
  10. 李笑来:7个习惯免费学好英语