管理信息系统与网站建设有什么区别,网络广告是什么,公司的网站开发服务费怎么入账,文章网站模板哪个好目录 一.Java的Cloneable和clone()方法
1.Object类中的clone()
2.实现Cloneable接口的类
3.通过clone()生成对象的特点
二.深拷贝和浅拷贝
1.浅拷贝
2.深拷贝
3.实现深拷贝的两种方法
1.一种是递归的进行拷贝
2.Json字符串的方式进行深拷贝 一.Java的Cloneable和clone…目录 一.Java的Cloneable和clone()方法
1.Object类中的clone()
2.实现Cloneable接口的类
3.通过clone()生成对象的特点
二.深拷贝和浅拷贝
1.浅拷贝
2.深拷贝
3.实现深拷贝的两种方法
1.一种是递归的进行拷贝
2.Json字符串的方式进行深拷贝 一.Java的Cloneable和clone()方法
1.Object类中的clone()
以下是Java中Object类中clone()方法,我们可以看到clone()方法是没有方法体的,因为clone是一个native类型的代码,具体的代码实现在JVM的c代码中实现,Java只是调用. 2.实现Cloneable接口的类
以下是Cloneable接口的内容,我们可以看到这个接口里面并没有实际的说明内容,这个接口的实现表示实现的类重写了clone()方法,可以进行对象的克隆. 现在我们实现Cloneable接口来创建一个类,这个类重写了clone(),并且根据重写的规则,这个方法的修饰必须比protected的权限更大,因此可以使用public方法,而且Object类中返回值是Object,我们这里重写的返回值可以为Dog,因为重写的规则规定返回值必须是instanceof Object,所以返回值可以为Dog.
public class Dog implements Cloneable{String name;int age;public Dog() {}public Dog(String name, int age) {this.name name;this.age age;}Overridepublic Dog clone() throws CloneNotSupportedException {return (Dog)super.clone();}Overridepublic String toString() {return Dog{ name name \ , age age };}
}
现在我们尝试用Dog类中的clone方法来克隆一个完全一样的对象 public static void main(String[] args) throws CloneNotSupportedException {Dog dog1 new Dog(张选宁, 2);Dog dog2 dog1.clone();System.out.println(dog1);System.out.println(dog2);System.out.println(dog1dog2);}
现在我们来思考一个问题,dog1和dog2是否指向的是同一个对象呢?我们有什么方法来验证是否为同一个对象呢?
这里提供两种方法来判断
使用号来进行判断 // 比较的是两个引用是否指向同一个对象 System.out.println(dog1dog2);//false 修改一个对象的属性,检查另一个对象的属性是否发生改变dog1.name薛程朗;System.out.println(dog1.name); //薛程朗System.out.println(dog2.name); //张选宁 因此我们从以上两个结果可以判断出,clone()方法产生的对象是指向不同引用的.
3.通过clone()生成对象的特点
上面我们通过两个结果已经总结出来了:clone()方法产生的对象是指向不同引用的.现在我们来具体的理解以下这两个对象.
根据下面两个图我们可以很直观的看出,这两个对象的地址不一样(也就是引用不一样),当改变一个对象的属性值的时候,另一个是不会发生改变的,clone()只是产生了一个属性相同的另一个对象 那么我们再来思考一个问题 ,如果这个类中包含了其他类型的对象,这个时候这个对象该如何拷贝呢?这就引出了我们的深拷贝和浅拷贝的概念了.
二.深拷贝和浅拷贝
以下是一个包含其他对象的类
public class Person implements Cloneable {String name;//包含了其他类型的对象Dog dog;public Person() {}Overridepublic Person clone() throws CloneNotSupportedException {return (Person) super.clone();}public Person(String name, Dog dog) {this.name name;this.dog dog;}Overridepublic String toString() {return Person{ name name \ , dog dog };}
}1.浅拷贝
接下来我们来验证是否克隆person1对象的时候,是否会将Person类中的Dog对象重现创建对象,还是仅仅是引用的复制(也就是地址相同的对象(同一个对象)) public static void main(String[] args) throws CloneNotSupportedException {Person person1 new Person(czj, new Dog(张选宁, 3));Person person2 person1.clone();System.out.println(person1.dogperson2.dog);//tureperson1.dog.name薛程朗;System.out.println(person1.dog.name);//薛程朗System.out.println(person2.dog.name);//薛程朗}
通过验证我们可以很清楚的看到仅仅是引用的复制,本质上里面的dog对象还是同一个对象,形象一点来说,也就是一个人,通过克隆技术又克隆出来了一个一模一样的人,但他们拥有的狗还是同一个狗.
接下来我们还是通过画图来明确这种拷贝方式的原理 这就是浅拷贝,只是将对象里面的对象引用进行了简单的拷贝,并没有将里面的对象进行new新建
接下来是网络上的定义:
浅拷贝是指只复制了对象的引用新对象和原对象引用的是同一个对象。因此当修改其中一个对象时另一个对象也会受到影响。浅拷贝通常只能复制基本数据类型和对其他对象的引用而不能复制其所引用的对象本身。
2.深拷贝
深拷贝其实就是不仅将需要克隆的对象进行拷贝了,也将对象里面的对象也进行了重新的拷贝. 这只是简单举例,不论有多少个对象,都会进行一一的进行拷贝处理,这种方法就叫做深拷贝.
接下来是网络上的定义:
深拷贝则是指复制了对象本身而不仅仅是对象的引用。因此新对象和原对象在内存中拥有不同的地址彼此之间没有任何关联。深拷贝通常能够完全复制原对象包括所有的属性和引用对象因此比浅拷贝更加安全和可靠。
3.实现深拷贝的两种方法
1.一种是递归的进行拷贝
具体应该将Person类中的clone()方法进行如下的修改 Overridepublic Person clone() throws CloneNotSupportedException {Person person(Person) super.clone();Dog dog1 person.dog.clone();person.dogdog1;return person;}
但是这种方法已经是很老旧的方法了,现在计算机实现已经不采用了这种方法了,现在使用的深拷贝方法是第二种方法.
2.Json字符串的方式进行深拷贝
使用JSON字符串进行深拷贝需要以下步骤
1.将对象转换为JSON字符串使用JSON库如Jackson、Gson或FastJSON将需要拷贝的对象转换为JSON字符串。
2.将JSON字符串转换回对象使用JSON库将JSON字符串转换回一个新的对象。
这将创建一个新的对象其属性与原始对象相同但是它们不会共享对象引用而是创建新的引用。
下面是一个使用Jackson库进行深拷贝的示例代码
import com.fasterxml.jackson.databind.ObjectMapper;public class DeepCopyUtils {private static final ObjectMapper objectMapper new ObjectMapper();public static T T deepCopy(T object) throws Exception {String jsonString objectMapper.writeValueAsString(object);return objectMapper.readValue(jsonString, (ClassT) object.getClass());}
}
在这个示例代码中我们使用Jackson的ObjectMapper类将对象转换为JSON字符串并将其转换回新的对象。