zoukankan      html  css  js  c++  java
  • java clone

    参考的文章地址如下:

    http://blog.csdn.net/zzp_403184692/article/details/8184751

    写的很详细,而且有例子,收货很多。

    看到别人提到clone,在此记录一下学习情况。

    首先要明确java的参数的传递方式。分为两种,一种是值传递,一种是引用传递。

    (1)java的参数传递都是按照值传递:按值传递 传递的是值的拷贝;按引用传递,传递的是对象引用的地址值,所以统称为值传递。

    (2)java中只有基本数据类型和String a = “bbb”; 这种直接使用双引号定义字符串方式的 String 是值传递,其余的都是引用传递。

    深拷贝和浅拷贝

    浅拷贝,直接将源对象的引用给新对象;深拷贝,将源对象的值给新对象。

    接下来进入文章主题,clone。

    在java中,以下的代码很常见,

    例子1,如下。

    import org.apache.log4j.Logger;

    public class CloneDemo {

        static Logger logger = Logger.getLogger(CloneDemo.class);  
        public static void main(String[] args) {
            Person p = new Person(20, "lee");
            Person p1 = p;
            
            logger.info("p " + p);
            logger.info("p " + p1);
            logger.info("p = p1 ?" + (p == p1));
            
            logger.info("p.age" + p.getAge());
            logger.info("p.name" + p.getName());
            logger.info("p1.age" + p1.getAge());
            logger.info("p1.name" + p1.getName());
            
            p.setAge(80);
            p.setName("batman");
            logger.info("p.age" + p.getAge());
            logger.info("p.name" + p.getName());
            logger.info("p1.age" + p1.getAge());
            logger.info("p1.name" + p1.getName());
        }
    }

    对象p1的引用指向了p,两者的引用是一样的,都指向一个对象。执行结果如下:

    [com.lee.demo.CloneDemo] - p com.lee.demo.Person@14989ff
    [com.lee.demo.CloneDemo] - p com.lee.demo.Person@14989ff
    [com.lee.demo.CloneDemo] - p = p1 ?true
    [com.lee.demo.CloneDemo] - p.age20
    [com.lee.demo.CloneDemo] - p.namelee
    [com.lee.demo.CloneDemo] - p1.age20
    [com.lee.demo.CloneDemo] - p1.namelee
    [com.lee.demo.CloneDemo] - p.age80
    [com.lee.demo.CloneDemo] - p.namebatman
    [com.lee.demo.CloneDemo] - p1.age80
    [com.lee.demo.CloneDemo] - p1.namebatman

    说明一下,Person p1 = p; 现在是对p p1的引用进行了操作,所以这是操作p,p1的值会发生变化。

    例子2,如下。

    接下来使用clone()来复制对象

    public class CloneDemo02 {
    
        static Logger logger = Logger.getLogger(CloneDemo02.class);  
        public static void main(String[] args) throws CloneNotSupportedException {
    
            Person p = new Person(23, "zhang");  
            Person p1 = (Person) p.clone();  
              
            logger.info("p " + p);
            logger.info("p " + p1);
            logger.info("p = p1 ?" + (p == p1));
            
            logger.info("p.age " + p.getAge());
            logger.info("p.name " + p.getName());
            logger.info("p1.age " + p1.getAge());
            logger.info("p1.name " + p1.getName());
            
            p.setAge(80);
            p.setName("batman");
            logger.info("p.age " + p.getAge());
            logger.info("p.name " + p.getName());
            logger.info("p1.age " + p1.getAge());
            logger.info("p1.name " + p1.getName());
        }
    }

    执行结果如下:

    [com.lee.demo.CloneDemo02] - p com.lee.demo.Person@14989ff
    [com.lee.demo.CloneDemo02] - p com.lee.demo.Person@1099f62
    [com.lee.demo.CloneDemo02] - p = p1 ?false
    [com.lee.demo.CloneDemo02] - p.age 23
    [com.lee.demo.CloneDemo02] - p.name zhang
    [com.lee.demo.CloneDemo02] - p1.age 23
    [com.lee.demo.CloneDemo02] - p1.name zhang
    [com.lee.demo.CloneDemo02] - p.age 80 [com.lee.demo.CloneDemo02] - p.name batman [com.lee.demo.CloneDemo02] - p1.age 23 [com.lee.demo.CloneDemo02] - p1.name zhang

    需要强调一些东西。clone() 是它自身Person对象的克隆,所以,p和p1的引用不是一个。此外用于,Person中的name,age的类型是String,int,也就是primitive,因此改变p后,p1不会随之变化。

    例子3,如下。

    public class Account implements Cloneable {

        Person person;
        long balance;
        @Override  
        public Object clone() throws CloneNotSupportedException {   
            return super.clone();   
        }  
    }

    public class Person implements Cloneable {

        Person (int age, String name) {
            this.age = age;
            this.name = name;
        }
        private int age;
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        private String name;
        
        @Override  
        protected Object clone() throws CloneNotSupportedException {  
            return (Person)super.clone();  
        }  
    }


    1
    public class CloneDemo03 { 2 3 static Logger logger = Logger.getLogger(CloneDemo03.class); 4 public static void main(String[] args) throws CloneNotSupportedException { 5 // TODO Auto-generated method stub 6 7 Person p = new Person(23, "zhang"); 8 Account account = new Account(); 9 account.balance = 1000; 10 account.person = p; 11 Account copy = (Account) account.clone();
    //balance因为是primitive,所以copy和原型是相等且独立的。 
    12 logger.info("copy.balance equals account.balance " + (copy.balance == account.balance)); 13 copy.balance = 2000; 14 logger.info("copy.balance equals account.balance " + (copy.balance == account.balance)); 15
    //person因为是引用类型,所以copy和原型的引用是同一的。 16 logger.info("copy.person equals account.person " + (copy.person == account.person)); 17 copy.person.setName("babyBoss"); 18 logger.info(account.person.getName()); 19 logger.info("copy.person.name equals account.person.name " + (copy.person.getName() == account.person.getName())); 20 } 21 22 }

    [com.lee.demo.CloneDemo03] - copy.balance equals account.balance true
    [com.lee.demo.CloneDemo03] - copy.balance equals account.balance false
    [com.lee.demo.CloneDemo03] - copy.person equals account.person true
    [com.lee.demo.CloneDemo03] - babyBoss
    [com.lee.demo.CloneDemo03] - copy.person.name equals account.person.name true

    primitive的确做到了相等且隔离,引用类型仅仅是复制了一下引用,copy和原型引用的东西是一样的,这就是所谓的浅拷贝。

    文章中,有些地方不是好理解,慢慢思考,跟着做例子。一步步来吧!我也是弄了很长时间。共勉。

    至于深拷贝怎么弄,我自己弄得不是很明白,推荐一篇文章,有兴趣的小伙伴们自己研究一下。

    http://blog.csdn.net/it_man/article/details/5744351

  • 相关阅读:
    uni-app在小程序开发者工具:TypeError: Cannot read property ‘forceUpdate‘ of undefined
    windows部署多个tomcat并添加到服务开机自动启动
    区域填充算法和多边形填充的扫描线算法[转]
    如何在不规则多边形内均匀撒点的算法[转]
    基于Living Atlas数据为木里山体滑坡敏感性建模【转】
    重磅!前端开发技术之Vue架构知识分享[转]
    如何使用 IAM 策略授予对特定 AWS S3 文件夹的用户特定访问权限?
    XXL-JOB安装、配置、启动、停止教程
    centos7 部署YApi
    CentOS 7安装MySQL8.0
  • 原文地址:https://www.cnblogs.com/lihao007/p/7224589.html
Copyright © 2011-2022 走看看