​Cloneable接口

news/2024/7/3 16:52:19

作者~小明学编程 

文章专栏JavaSE基础

格言目之所及皆为回忆,心之所想皆为过往
在这里插入图片描述

目录

Cloneable接口

浅拷贝

深拷贝


Cloneable接口

Java 中内置了一些很有用的接口, Clonable 就是其中之一,Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 "拷贝". 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常。

下面给大家一个实例:

浅拷贝

定义:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。”里面的对象“会在原来的对象和它的副本之间共享。

class Person implements Cloneable{
    public int age;
    public void eat() {
        System.out.println("eat()");
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class TestDome {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        person.age = 100;
        Person person2 = (Person) person.clone();
        System.out.println(person2);
    }
}

这里我们是通过实现接口进行了一个浅拷贝。

public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        person.age = 100;
        Person person2 = (Person) person.clone();
        person2.age = 10;
        System.out.println(person);
        System.out.println(person2);
    }

我们这里对person2的age进行一个更改然后我们接着输出person和person2我们看到结果。

 深拷贝

定义:深拷贝是一个整个独立的对象拷贝,深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。

class Money {
    public int m = 88;
}
class Person implements Cloneable{
    public int age;
    public Money money = new Money();
    public void eat() {
        System.out.println("eat()");
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class TestDome {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        Person person2 = (Person) person.clone();
        System.out.println(person.money.m);
        System.out.println(person2.money.m);
        System.out.println("----------------------");
        person2.money.m = 99;
        System.out.println(person.money.m);
        System.out.println(person2.money.m);
    }
    
}

 这里我们看到我们打印的都是99,这是因为啥呢,我们前面所进行的拷贝只是单纯的一个拷贝,不会拷贝我们对象里面的对象所以我们person和person2都是公用同一个Money类的,要想解决这个问题我们就得对对象里面的对象也进行拷贝,这里就叫做我们的深拷贝。

class Money implements Cloneable{
    public int m = 88;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{
    public int age;
    public Money money = new Money();
    public void eat() {
        System.out.println("eat()");
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tem = (Person) super.clone();
        tem.money = (Money) this.money.clone();
        return tem;
    }
}
public class TestDome {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        Person person2 = (Person) person.clone();
        System.out.println(person.money.m);
        System.out.println(person2.money.m);
        System.out.println("----------------------");
        person2.money.m = 99;
        System.out.println(person.money.m);
        System.out.println(person2.money.m);
    }
    
}

首先我们的Money类要实现一个cloneable的接口才能对我们当前的类进行一个拷贝,之后就是重写我们的clone方法.

protected Object clone() throws CloneNotSupportedException {
        Person tem = (Person) super.clone();
        tem.money = (Money) this.money.clone();
        return tem;
    }

首先定义一个临时的变量tem,并且将super.clone()强转为Person之后找到我们对象里面的Money对象再进行一个强转操作,最后进行返回。

 这里我们就实现了深拷贝。


http://lihuaxi.xjx100.cn/news/49768.html

相关文章

浅谈Git架构和如何避免代码覆盖的事故

浅谈Git架构和如何避免代码覆盖的事故 Git 不同于 SVN 的地方在于, Git 是分布式的版本管理系统, 所有的客户端和服务器都保存了一份代码, 涉及到仓库仓之间的同步, 所以处理不当极易造成冲突 最直接的方法就是不让新手合并代码 PR 开发: GitHub 开源项目常用开发方式, 开发…

[HJ60 查找组成一个偶数最接近的两个素数]

描述 任意一个偶数(大于2)都可以由2个素数组成,组成偶数的2个素数有很多种情况,本题目要求输出组成指定偶数的两个素数差值最小的素数对。 数据范围:输入的数据满足 4≤n≤1000 输入描述: 输入一个大于…

Python 全栈系列190 全栈能力组建进展梳理

说明 从数据处理的应用角度,梳理一下目前全栈能力的情况。 内容 简单的分为四部分: 1 存储2 处理3 (调度)机制4 监控/管理1 存储【保持使用】 这部分我觉得已经ok了 ⋆ ⋆ ⋆ ⋆ ⋆ \star\star\star\star\star ⋆⋆⋆

led点阵屏静态图

话不多说&#xff0c;上代码&#xff0c;前提是你已经知道各行代码的意思。跟着老师的代码走最好&#xff0c;每一行都一样&#xff0c;要不然会有意想不到的错误&#xff0c;小白阶段就不要自己创新代码了。X﹏X #include <REGX52.H> sbit RCKP3^5; //RCLK sbit SCKP3^6…

C# 多线程二:Interlocked 互锁的理解和简单示例

一.多线程的线程安全 多线程安全问题原因是在cpu执行多线程时&#xff0c;在执行的过程中可能随时切换到其他的线程上执行&#xff0c;当多个线程同时操作同一个变量时&#xff0c;如果不施加其他措施&#xff0c;可能导致错误数据的出现 二.Interlocked的特点 Interlocked是…

JavaWeb - 15 异步请求 Ajax axios

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录1.同步请求与异步请求1.1 同步请求1.2 异步请求2. Ajax发送异步请求2.1 Ajax概述2.2 原生JS实现AJAX详解2.3 代码码演示3. axios框架3.1 axios概述3.2 安装方式3.3 快…

【Linux从0到1】第十七篇:高级IO

文章目录一、五种IO模型二、高级IO重要概念2.1 同步通信 vs 异步通信(synchronous communication/ asynchronouscommunication)2.2 阻塞 vs 非阻塞2.3 其他高级IO2.4 非阻塞IO2.5 I/O多路转接之select2.6 I/O多路转接之poll [选学]2.7 I/O多路转接之epoll一、五种IO模型 阻塞IO…

SpringMVC处理Ajax请求及处理和响应json格式的数据

在SpringMVC中处理Ajax的请求可以用到RequestBody与ResponseBody注解实现 1.RequestBody:将请求体中的内容和控制器方法的形参进行绑定 2.使用RequestBody注解将json格式的请求参数转换程Java对象&#xff08;三个步骤&#xff09; a>导入Jackson的依赖 b>在SpringMVC的…