0
点赞
收藏
分享

微信扫一扫

java clone 阐述

林塬 2023-11-22 阅读 48



文章目录

  • 1、为什么要clone
  • 2、new 对象和 clone 对象的区别
  • 3、clone 对象的使用
  • 1) 我们 先看 一下 赋值引用;
  • 2)下面我们看一下克隆一个对象:
  • 4、clone 分为 浅拷贝 和 深拷贝
  • 1) 浅拷贝
  • 2)、深拷贝
  • 3)、浅拷贝示例
  • 4)、深拷贝的例子


1、为什么要clone

当一个对象需要被多人操作,但是又不相互影响,需要保持原对象的状态,这时就会克隆出许多不同的对象。

2、new 对象和 clone 对象的区别

new 操作 本质是操作内存。程序在执行new操作的时候,首先看到的是new
操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存后,在调用构造函数,填充对象的各个域,这一步叫做对象的初始化。构造方法创建完成之后,可以吧他的引用(地址)发布到外部,就可以在外部引用操纵这个对象。
clone 在第一步 和new 相似,都是分配内存,调用clone 方法时,分配的内存和原对象(调用clone方法的原对象),然后再使用对象中对应的各个域,填充新的对象的域,填充完成后,clone 方法返回,一个新的相同的对象被创建,同样可以把新的对象那个的引用发布到外部。

3、clone 对象的使用
1) 我们 先看 一下 赋值引用;

package com.example.lum.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Person testObjectOne;
        Person testObjectTwo;
        testObjectOne = new Person(28,"lu"); //新建 一个对象 one
        testObjectTwo = testObjectOne;  //将 one 赋值给 Twos
        System.out.println("``````````````");
        System.out.println(testObjectOne);
        System.out.println(testObjectTwo);
        System.out.println("``````````````");
    }

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


}

log 显示:

java clone 阐述_ide

我们可以看到打印的地址值是相同的,那肯定是一个对象。
testObjectOne,testObjectTwo 只是引用而已,都指向一个相同的对象 Person。
可以把这种现象叫做引用的复制:

java clone 阐述_System_02

2)下面我们看一下克隆一个对象:

这个时候 Person 类需要继承 Cloneable 实现 clone 接口

package com.example.lum.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
        Person testObjectOne;
        Person testObjectTwo;
        testObjectOne = new Person(28,"lu"); //新建 一个对象 one
        testObjectTwo = (Person) testObjectOne.clone();  //将 one 克隆Two
        System.out.println("``````````````");
        System.out.println(testObjectOne);
        System.out.println(testObjectTwo);
        System.out.println("``````````````");

        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }

  class Person implements Cloneable {
        private  int  age;
        private  String  name ;
        public  Person(int age,String name){
            this.age = age;
            this.name = name;
        }
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return (Person)super.clone();
        }
    }
}

log显示:

java clone 阐述_ide_03


我们可以看到

java clone 阐述_System_04

4、clone 分为 浅拷贝 和 深拷贝

就像我们的类一样,里面有 变量,age ,name 。
age 是基础数据类型,在clone 时直接 将一个4字节数值拷贝过来,
name 是String 类型,它是一个引用,指向String 对象。那么对它的clone有两种,一种是将引用拷给新的对象,一种是将最它指向的字符串对象clone出来,赋值给新的对象。
这两种方式 一个是浅拷贝,一个是深拷贝

1) 浅拷贝

java clone 阐述_System_05

2)、深拷贝

java clone 阐述_浅拷贝_06

3)、浅拷贝示例

我们上面代码就是浅拷贝示例,我们比较下拷贝对象里的 name 地址 和 原对象地址是否一样

package com.example.lum.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
        Person testObjectOne;
        Person testObjectTwo;
        testObjectOne = new Person(28,"lu"); //新建 一个对象 one
        testObjectTwo = (Person) testObjectOne.clone();  //将 one 赋值给 Twos
        System.out.println("``````````````");
        System.out.println(testObjectOne.getName());
        System.out.println(testObjectTwo.getName());
        System.out.println((testObjectOne.getName() == testObjectTwo.getName()));

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

        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }

    class Person implements Cloneable {
        private  int  age;
        private  String  name ;
        public  Person(int age,String name){
            this.age = age;
            this.name = name;
        }
        public int  getAge(){
            return  this.age;
        }

        public  String   getName (){
            return  this.name;
        }

        @Override
        protected Object clone() throws CloneNotSupportedException {
            return (Person)super.clone();
        }
    }

}

打印的 log:

java clone 阐述_ide_07

4)、深拷贝的例子

我们在年龄,姓名,之上添加一个灵魂

package com.example.lum.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import java.net.Socket;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
        Person testObjectOne;
        Person testObjectTwo;
        testObjectOne = new Person(28,"lu",new Soul()); //新建 一个对象 one
        testObjectTwo = (Person) testObjectOne.clone();  //将 one 赋值给 Twos
        System.out.println("``````````````");
        System.out.println(testObjectOne.getName());
        System.out.println(testObjectTwo.getName());
        System.out.println((testObjectOne.getName() == testObjectTwo.getName()));
        System.out.println(testObjectOne.getSoul());
        System.out.println(testObjectTwo.getSoul());
        System.out.println((testObjectOne.getSoul() == testObjectTwo.getSoul()));
        System.out.println("``````````````");

        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }

    class Person implements Cloneable {
        private  int  age;
        private  String  name ;
        private Soul soul;
        public  Person(int age,String name, Soul soul){
            this.age = age;
            this.name = name;
            this.soul = soul;
        }
        public int  getAge(){
            return  this.age;
        }

        public  String   getName (){
            return  this.name;
        }


        public  Soul   getSoul (){
            return  this.soul;
        }

        @Override
        protected Object clone() throws CloneNotSupportedException {
            Person person = (Person) super.clone();  // 回调 clone 方法 新建Person 对象
            person.soul = (Soul) soul.clone(); //同时 对象 里的 灵魂对象 clone 自身父类
            return person;
        }
    }

//新建灵魂对象 同时 也 添加 Cloneable 接口
    class  Soul  implements  Cloneable{
        public Soul(){}
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return (Soul)super.clone();
        }
    }
}

log :

java clone 阐述_ide_08

我们可以看到 灵魂的对象他们clone 前后的地址是不一样的。
就是深克隆 ,克隆的对象里的对象也要克隆。


举报

相关推荐

0 条评论