如何通过JVM角度谈谈Java的clone操作
作者:占小狼 发布时间:2023-10-13 09:54:40
前言
最近在给熔断器组件增加一个降级策略(Hystrix好像没有这个配置),我们提供了如下几种策略:
1、默认策略
2、返回常量值
3、抛出指定异常
4、执行一段groovy脚本
当然了,这些配置都是可以在平台上配置,并立即生效的。
目前返回常量值的实现如下:
今天发现,如果每次都返回同一个对象,而且这个逻辑对业务来说是黑盒(业务不知道每次拿到的对象是同一个),如果对这个对象进行了操作,那肯定会影响到其它的请求,为了避免背锅,我们需要每次返回一个新的对象,第一反应是通过clone是否可行(因为每次json的序列化也会损耗性能),但是jdk自带的clone方法只是浅克隆,如果对象中包含了另一个复杂对象,clone出来的对象还是存在被修改的风险。
详细介绍:
大家可以看下面一个例子:
class Master {
String name;
public Master(String name) {
this.name = name;
}
}
初始化一个Master类
class Dog implements Cloneable {
String name;
int age;
Master master;
public Dog(String name, int age, Master master) {
this.name = name;
this.age = age;
this.master = master;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "{name:" + name + ", age: " + age + ", master: "+ master.name + "}";
}
}
再初始化一条狗
public static void main(String[] args) throws Exception {
Master master = new Master("zj0");
Dog dog1 = new Dog("旺财", 1, master);
Dog dog2 = (Dog)dog1.clone();
dog1.name = "比利";
dog1.master.name = "zj1";
System.out.println(dog2);
}
最后运行一下,结果如下:
{name:旺财, age: 1, master: zj1}
dog1是原始狗,dog2是克隆出来的,但是我修改dog1的master的name时,克隆的master也跟着变化了,这显然不行。
虽然一直都知道Object的clone方法是浅克隆,也一直没继续探索一下,今天碰到了就顺手看下JVM的实现,好像很简单,在jvm.cpp文件中,搜索"JVM_Clone"
以前一直没用过clone这个方法,通过源码发现在运行的时候会检查类是否实现Cloneable接口,编译的时候不检查,想啥呢?
根据对象或者数据的大小,从堆中开辟一块同等大小的内存,然后把原始对象的数据都复制到新的内存地址,对于基本类型,可以把原始值复制过来,但是对于内部对象来说,其保存的只是一个地址,复制时也是对地址的复制,最终还是指向同一个对象,所以就造成了上述的问题。
来源:https://www.jianshu.com/p/309f80f33190


猜你喜欢
- 本文实例为大家分享了Android实现简单顶部标题栏的具体代码,供大家参考,具体内容如下实现功能:1)自定义View标题栏布局;2)灵活的可
- 一、Android Studio 主题的设置1.1 设置Android Studio 自带的主题及包名字体大小1.2 导入第三方主题:下载了
- 1. 需求描述有这样一个需求,用ViewPager实现图片滑动,其下方有一个tab,每一个tab的标签对应一组图片,在ViewPager中的
- 避免"索引越界"错误的规则如下(针对C++):不要使用静态或动态分配的数组,改用array或vector模板不要使用带方
- 本文实例讲述了Android编程获取网络连接方式及判断手机卡所属运营商的方法。分享给大家供大家参考,具体如下:问题:项目中写的网络模块,感觉
- 本文实例为大家分享了Android自定义StepView配送进度展示的具体代码,供大家参考,具体内容如下效果图使用可在layout文件下设置
- 本文项目为大家分享了Java实现 * 面五子棋的具体代码,供大家参考,具体内容如下项目介绍:本次设计是基于知识点Java类和对象以及数组开发的
- 一、MessageBox弹出框MessageBox.Show(<字符串> Text, <字符串> Title, &l
- 前言之前写过几篇关于输入系统的文章,但是还没有写完,后来由于工作的变动,这个事情就一直耽搁了。而现在,在工作中,遇到输入系统相关的事情也越来
- 这几天在做公司年会的一个抽奖软件,开始做的的时候,认为算法是很简单的,把员工的数据放进list里,把list的标号作为需要获取的随机数,根据
- 前言Spark Sql可以通过UDF来对DataFrame的Column进行自定义操作。在特定场景下定义UDF可能需要用到Spark Con
- Knife4j就相当于是swagger的升级版,对于我来说,它比swagger要好用得多1、在pom.xml引入依赖包<!-- Swa
- 1.Object类是什么?🟪Object 是 Java 类库中的一个特殊类,也是所有类的父类。也就是说,Java 允许把任何类型的
- 1.多数元素题目描述思路详解这个思路比较简单,先排序,排序过后遍历如果后一个等于前一个输出就好代码与结果class Solution { &
- 之前写过3篇手势密码的demo,不过没有集成到真实的企业项目中,这几天正好领到一个手势密码项目,昨天刚好弄完,今天抽空整理下,目前还没有完善
- 我们在日常开发中,经常会遇到类似的场景:当要做一件事儿的时候,这件事儿的步骤是固定好的,但是每一个步骤的具体实现方式是不一定的。通常,遇到这
- 方式1:1. 明确 Spark中Job 与 Streaming中 Job 的区别1.1 Spark Core一个 RDD DAG Graph
- 一、下载安装包 1. JDK1.8百度云下载路径:百度网盘下载链接: https://pan.baidu
- 前不久,我们发布了《选择 .NET 的 n 个理由》。它提供了对平台的高层次概述,总结了各种组件和设计决策,并承诺对所涉及的领域发表更深入的
- Spring框架的关键组件是面向方面编程(AOP)框架。面向方面的编程不仅打破程序逻辑分成不同的部分称为所谓的担忧。跨越多个点的应用程序的功