CloneNotSupportedException的解决方案 + Object的clone方法分析

CloneNotSupportedException的解决方案

引入问题:

在一次测试clone方法时,D类Override了Object类的clone方法

public class D {private Integer A1;private Integer A2;public D() {}public D(Integer a1, Integer a2 {A1 = a1;A2 = a2;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
123456789101112131415161718

在测试类中执行clone方法报错了

public class Test5 {public static void main(String[] args) {D p  = new D();D p2 = null;try {p2 = (D)p.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}System.out.println(p == p2);}}
12345678910111213141516

在这里插入图片描述

抛出了 CloneNotSupportedException

寻找原因:

既然是重写自Object的clone方法,那么去看看Object对该方法的定义:

protected native Object clone() throws CloneNotSupportedException;
1

其中对于异常抛出的描述如下:

Throws:
CloneNotSupportedException – if the object’s class does not support the Cloneable interface. Subclasses that override the clone method can also throw this exception to indicate that an instance cannot be cloned.

如果对象的class不实现Cloneable接口,子类重写clone方法会同样抛出异常表示实例不能被克隆;

哦?

那不意思就是说:你要不父类实现Cloneable接口,要不就子类实现Cloneable

两个测试代码:

测试1: 在父类上实现Cloneable接口

public class TestClone {public static void main(String[] args) throws CloneNotSupportedException {Father father = new Father();Father fatherClone = (Father) father.clone();Son son = new Son();Son sonClone = (Son) son.clone();System.out.println(father==fatherClone);System.out.println(son==sonClone);}}class Father implements Cloneable{private Integer f1;private Integer f2;public Father() {}public Father(Integer f1, Integer f2) {this.f1 = f1;this.f2 = f2;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}class Son extends Father{private Integer s1;private Integer s2;public Son() {}public Son(Integer s1, Integer s2) {this.s1 = s1;this.s2 = s2;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152

不出意外,没有任何问题

在这里插入图片描述

测试2:在子类上实现Cloneable接口

public class TestClone {public static void main(String[] args) throws CloneNotSupportedException {
//        Father father = new Father();
//        Father fatherClone = (Father) father.clone();Son son = new Son();Son sonClone = (Son) son.clone();//        System.out.println(father==fatherClone);System.out.println(son==sonClone);}}class Father {private Integer f1;private Integer f2;public Father() {}public Father(Integer f1, Integer f2) {this.f1 = f1;this.f2 = f2;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}class Son extends Father implements Cloneable{private Integer s1;private Integer s2;public Son() {}public Son(Integer s1, Integer s2) {this.s1 = s1;this.s2 = s2;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152

执行父类的clone报错,但是执行子类的clone没得问题

在这里插入图片描述

SO:

哪个类的需要clone,就在那个类在重写clone方法,并且在那个类或者其父类中实现Cloneable接口

详细分析clone方法的实现:

由于Object的clone方法是native修饰的,也就是虚拟机内部实现的方法

根据Hotspot虚拟机定义,找到Object.c

在这里插入图片描述

为什么要实现Cloneable接口?

在JVM_Clone方法中有这样一段判断:

在这里插入图片描述

很明显,虚拟机给你抛出的异常

为什么会出现地址不同的情况?

在这里插入图片描述

很明显,直接在堆内存中执行allocate方法开辟新的对象空间

并返回一个 oop 对象,也就是对象描述的指针(指向对象的首地址)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/311866.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker:Docker集群配置与应用(Docker Swarm)

Docker集群配置与应用 前言学习目标 1. 建立Docker Swarm集群1.1 为什么要使用容器集群1.2 什么是Swarm集群1.3 Docker Swarm特性1.4 Swarm节点1.5 Swarm 集群管理命令Swarm 集群节点管理命令 1.6 Docker Swarm 集群搭建 前言 可以认为Docker Swarm(Go语言开发)将一个Docker主…

Powermill各版本安装指南

下载链接 https://pan.baidu.com/s/1CsrYEUQNmDa820RxDV2G6Q?pwd0531 1.鼠标右击【PowerMill2024(64bit)】压缩包(win11及以上系统需先点击“显示更多选项”)【解压到 PowerMill2024(64bit)】。 2.打开解压后的文件夹,双击打开【Setup】文…

CorelDRAW 2024最新版本功能介绍含注册机序列号

始于1989年并不断推陈出新,致力为设计工作者提供更高效的设计工具!CorelDRAW滋养并见证了一代设计师的成长!在最短的时间内交付作品,CorelDRAW的智能高效会让你一见钟情!CorelDRAW 全称“CorelDRAW Graphics Suite“,也…

JUC Lock 锁入门

文章目录 死锁(Deadlock)通过 Visualvm 等工具排查死锁 活锁park & unpark与 wait & notify 的区别park & unpark 实现:点外卖 Lock 对象ReentrantLock 可重入锁可重入lockInterruptibly 方法上锁(可打断)…

语义分割的应用及发展

语义分割(Semantic Segmentation)是一种计算机视觉领域的任务,旨在将一张图像中的每一个像素都分配一个语义标签,即将图像中的每个物体区域进行精确的分类划分。例如,在一张街景图中,语义分割可以将人、车、路、天空等每个像素分别…

十大排序算法归纳

目录 排序算法的分类 插入排序算法模板 选择排序算法模板 冒泡排序算法模板 希尔排序算法模板 快速排序算法模板 归并排序算法模板 堆排序算法模板 基数排序算法模板 计算排序算法模板 桶排序算法模板 排序算法的分类 插入:插入,折半插入&am…

非科班,培训出身,怎么进大厂?

今天分享一下我是怎么进大厂的经历,希望能给大家带来一点点启发! 阿七毕业于上海一所大学的管理学院,在读期间没写过一行 Java 代码。毕业之后二战考研失利。 回过头来看,也很庆幸这次考研失利,因为这个时候对社会一…

linux go环境安装 swag

下载依赖包 go get -u github.com/swaggo/swag编译 移动到下载的go-swagger包目录,一般在$GOPATH/pkg/mod下 查看 GOPATH echo $GOPATHcd /root/GolangProjects/pkg/mod/github.com/swaggo/swagv1.16.2go install ./cmd/swag/不出意外,$GOPATH/bin下 已经有了sw…

基于CMake的大型C++工程组织

此文适合大型C工程,涉及到多个自定义库,多个第三方库,以及还有给第三方用户进行二次开发的需求下,应对这种复杂编译环境下的工程组织方式的一些经验介绍,希望给大型工业软件的开发者一些参考 一个大型工程&#xff0c…

数据结构—树的应用

文章目录 11.树的应用(1).Huffman树#1.加权外部路径长度#2.Huffman算法#3.Huffman编码 (2).二叉搜索树#1.基本定义#2.查找#3.插入结点#4.构建树#5.查找最小值和最大值#6.删除结点#7.一个问题 (3).平衡搜索树#1.满二叉树、完全二叉树和丰满二叉树#2.平衡因子和平衡树#3.左旋与右…

图像中的傅里叶变换及低通与高通滤波

傅里叶变换 高频:在图像中变化剧烈的灰度分量,如边界。 低频:在图像中变化缓慢的灰度分量。 OpenCV中函数为cv2.dft()和cv2.idft(),输入图像要先转换成np.float32格式。得到的结果频率为0的部分会在左上角,为方便处理…

【ROS2】MOMO的鱼香ROS2(二)ROS2入门篇——ROS2初体验

ROS2初体验 引言专业术语认识1 认识ROS21.1 ROS2版本对照表1.2 ROS与ROS2对比1.3 ROS2架构1.3.1 DDS实现层1.3.2 ROS中间件接口(RMW)1.3.3 ROS2客户端库 RCL 2 安装ROS22.1 ROS安装(一键式)2.2 手动安装ROS22.2.1 添加ROS软件源2.…