Java工程师知识树 / Java基础
Java对象的复制方式:
- 直接赋值赋值
- 浅复制
- 深复制
对象的复制方式使用案例解释.
具体问题:
A与B是两个独立的对象,但B的初始值是由A对象确定
package com.study.jvm;
public class ObjectClone {
public static void main(String[] args) {
Student student1 = new Student();
student1.setStudyNum("001");
Student student2 = student1;
student2.setStudyNum("002");
System.out.println("学生1的学号"+student1.getStudyNum());
System.out.println("学生2的学号"+student2.getStudyNum());
}
}
class Student{
private String studyNum;
public String getStudyNum() {
return studyNum;
}
public void setStudyNum(String studyNum) {
this.studyNum = studyNum;
}
}
// print
学生1的学号002
学生2的学号002
原因:
student1的引用赋值给student2,实际上student1和student2指向内存堆中同一个对象,所以修改哪个对象都会打印相同的结果。
解决方案
A与B是两个独立的对象,但B的初始值是由A对象确定,使得两个对象独立的解决方案有:
(1)将A对象的值分别通过set方法加入B对象中;直接赋值赋值
(2)通过重写java.lang.Object类中的方法clone();浅复制与深复制
(3)通过第三方工具类BeanUtil进行对象复制,原理都是get所有原对象的属性值然后给新对象的对应属性set值;cn.hutool.core.bean.BeanUtil; 直接赋值赋值
(4)通过序列化实现对象的复制;深复制
解法方案使用实例
package com.study.jvm;
public class ObjectClone {
public static void main(String[] args) throws CloneNotSupportedException {
Student student1 = new Student();
student1.setStudyNum("001");
student1.setAge(1);
System.out.println("学生1的学号" + student1.toString());
Student student2 = student1;
student2.setStudyNum("002");
student2.setAge(2);
System.out.println("学生2的学号" + student2.toString());
Classes classes1 = new Classes();
classes1.setNum(36);
System.out.println("班级1的班级号" + classes1.toString());
Classes classes2 = classes1.clone();
classes2.setNum(35);
System.out.println("班级2的班级号" + classes2.toString());
Student student3 = new Student();
student3.setStudyNum("003");
student3.setAge(3);
System.out.println("学生3的学号" + student3.toString());
Student student4 = student1.clone();
student4.setStudyNum("004");
student4.setAge(4);
System.out.println("学生4的学号" + student4.toString());
Student student5 = new Student();
student5.setStudyNum("005");
student5.setAge(5);
student5.setClasses(classes1);
System.out.println("学生5的学号" + student5.toString());
Student student6 = student5.clone();
System.out.println("学生6的学号" + student6.toString());
student6.setStudyNum("006");
student6.setAge(6);
student6.setClasses(classes2);
System.out.println("学生6的学号" + student6.toString());
}
}
class Student implements Cloneable{
private String studyNum;
private int age;
private Classes classes;
public String getStudyNum() {
return studyNum;
}
public void setStudyNum(String studyNum) {
this.studyNum = studyNum;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Classes getClasses() {
return classes;
}
public void setClasses(Classes classes) {
this.classes = classes;
}
@Override
protected Student clone() {
Student stu = null;
try {
// 基础数据类型 与 引用类型 分别复制
stu = (Student) super.clone();// 基础数据类型
if (classes != null) {
stu.classes = classes.clone();// 引用类型
}
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return stu;
}
@Override
public String toString() {
return "Student{" +
"studyNum='" + studyNum + '\'' +
", age=" + age +
'}';
}
}
class Classes implements Cloneable{
private int num;
@Override
protected Classes clone() throws CloneNotSupportedException {
return (Classes) super.clone();
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public String toString() {
return "Classes{" +
"num=" + num +
'}';
}
}
序列号方式拷贝对象
package com.study.jvm;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
* 序列号方式拷贝对象
* 属于深拷贝
*/
class Body implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private Fonter fonter;
private Head head;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Fonter getFonter() {
return fonter;
}
public void setFonter(Fonter fonter) {
this.fonter = fonter;
}
public Head getHead() {
return head;
}
public void setHead(Head head) {
this.head = head;
}
@Override
public String toString() {
return "Body [name=" + name + ", fonter=" + fonter + ", head=" + head + "]";
}
public Body(String name, Fonter fonter, Head head) {
super();
this.name = name;
this.fonter = fonter;
this.head = head;
}
}
class Head implements Serializable {
private static final long serialVersionUID = 1L;
private Integer size;
}
class Fonter implements Serializable {
private static final long serialVersionUID = 1L;
private Integer size;
}
class Face implements Serializable {
private static final long serialVersionUID = 1L;
private Integer size;
}
public class ObjClonerSeiz {
private static T CloneObj(T obj) {
T retobj = null;
try {
//写入流中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
//从流中读取
ObjectInputStream ios = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
retobj = (T) ios.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return retobj;
}
public static void main(String[] args) {
Body body = new Body("张三", new Fonter(), new Head());
Body body2 = CloneObj(body);
System.out.println("body==body2 ====>" + (body == body2));
System.out.println("body.font==body2.font ====>" + (body.getFonter() == body2.getFonter()));
System.out.println("body.head==body2.head ====>" + (body.getHead() == body2.getHead()));
}
}