zoukankan      html  css  js  c++  java
  • 克隆

    为什么要克隆

    package algorithm;
    
    public class Person {
    
    	private String name;
    
    	public Person() {
    	}
    
    	public Person(String name) {
    		this.name = name;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public String toString(){
    		return "name="+name;
    	}
    }
    
    public class Test{
      public static void main(String[] args) throws Exception { Person person1 = new Person("a"); System.out.println("person1:"+person1); Person person2 = person1; System.out.println("person2:"+person2); System.out.println("person2中name修改为b"); person2.setName("b"); System.out.println("person1:"+person1);   }
    }

     person1:name=a
    person2:name=a
    person2中name修改为b
    person1:name=b

    这就是没有克隆出现的问题,因为只是引用的赋值,它们指向同一对象,如果一个修改另一个也会影响。所以我们需要克隆一个对象,让它们指向不同的对象。

    Object的clone()被声明为proctected,那么根据http://www.cnblogs.com/tp123/p/6406576.html中对protected的描述,可以知道我们想要某个类使用clone方法,就必须在该类中重写clone方法(否则就只能在该类中调用)。

    对于上面的就是在Person里面可以通过this.clone()或super.clone(),new Person().clone()来调用,但是在Test中就不可以通过Person person1 = new Person("a");person1.clone();Test自身也是可以调用。

    但是要求调用clone方法的对象必须实现cloneable,如果没有实现该接口就会报错。

    所以一般要使用clone方法

    1.实现cloneable接口,表示这是一个可clone的对象。

    2.重写一个public的clone方法。
     

     克隆的例子

    package algorithm;
    
    public class Person implements Cloneable{
    
    	private String name;
    
    	public Person() {
    		System.out.println("执行person的构造方法");
    	}
    
    	public Person(String name) {
    		this.name = name;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public Person clone() throws CloneNotSupportedException {
    		return (Person)super.clone();
    	}
    
    	public String toString(){
    		return "name="+name;
    	}
    	
    }
    
    public static void main(String[] args) throws Exception{
    		Person p1 = new Person();
    		p1.setName("person1");
    		System.out.println("p1:"+p1);
    		Person p2 = p1.clone();
    		System.out.println("p2:"+p2);
    		p2.setName("person2");
    		System.out.println("p2修改后");
    		System.out.println("p1:"+p1);
    		System.out.println("p2:"+p2);
    	}
    

     结果

    执行person的构造方法
    p1:name=person1
    p2:name=person1
    p2修改后
    p1:name=person1
    p2:name=person2
    

     从结果可以看出

    1.java克隆调用的根本还是Object的克隆方法。

    2.clone方法并没有调用构造方法。(因为只有一次调用构造方法,是new的时候调用的)。     clone方法是一个native方法,应该是c++直接内存复制产生一个新对象。

    3.调用clone方法确实产生了新的对象,所以修改person2的内容不会修改person1。

    浅克隆和深克隆

    1.浅克隆,就是表层的克隆,也就是只对最外层的对象进行克隆,而里面的所有引用的对象并没有克隆,只克隆了这些对象的地址。

    2.深克隆,就是除了克隆自己也克隆所有里面的对象实例。

    如果要深克隆,有两种办法。

    1.对对象序列化,然后反序列化。

    2.先调用super.clone()方法克隆出一个新对象来,然后在子类的clone()方法中手动给克隆出来的非基本数据类型(引用类型)赋值。

  • 相关阅读:
    Maidsafe-去中心化互联网白皮书
    The Top 20 Cybersecurity Startups To Watch In 2021 Based On Crunchbase
    Top 10 Blockchain Security and Smart Contract Audit Companies
    The 20 Best Cybersecurity Startups To Watch In 2020
    Blockchain In Cybersecurity: 11 Startups To Watch In 2019
    004-STM32+BC26丨260Y基本控制篇(阿里云物联网平台)-在阿里云物联网平台上一型一密动态注册设备(Android)
    涂鸦开发-单片机+涂鸦模组开发+OTA
    000-ESP32学习开发-ESP32烧录板使用说明
    03-STM32+Air724UG远程升级篇OTA(阿里云物联网平台)-STM32+Air724UG使用阿里云物联网平台OTA远程更新STM32程序
    03-STM32+Air724UG远程升级篇OTA(自建物联网平台)-STM32+Air724UG实现利用http/https远程更新STM32程序(TCP指令,单片机程序检查更新)
  • 原文地址:https://www.cnblogs.com/tp123/p/6403067.html
Copyright © 2011-2022 走看看