1、什么叫Java浅拷贝?
浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。
2、什么叫Java深拷贝?
深拷贝复制变量值,对于引用数据,则递归至基本类型后,再复制。深拷贝后的对象与原来的对象是完全隔离的,互不影响,对一个对象的修改并不会影响另一个对象。深拷贝相比于浅拷贝速度较慢并且花销较大。
3、Java浅拷贝和深拷贝的区别是什么?
通俗来讲浅拷贝的复制其引用,当引用指向的值改变时也会跟着变化;而深拷贝则是与原来的对象完全隔离,互不影响。
深拷贝的实现方法主要有两种:
(1) 通过重写clone方法来实现深拷贝(实现Cloneable接口)
推荐】慎用 Object 的 clone 方法来拷贝对象。
说明: 对象的 clone 方法默认是浅拷贝,若想实现深拷贝需要重写 clone 方法实现属性对象的拷贝。
与通过重写clone方法实现浅拷贝的基本思路一样,只需要为对象图的每一层的每一个对象都实现Clonneable接口并重写clone方法,最后在最顶层的类的重写的clone方法中调用所有的clone方法即可实现深拷贝。简单的说就是“每一层的每个对象都进行浅拷贝=深拷贝。
(2)推荐: 通过对象序列化实现深拷贝(实现Serializable接口)
虽然层次调用clone方法可以实现深拷贝,但是显然代码量实在太大。特别对于属性数量比较多、层次比较深的类而言,每个类都要重写clone方法太过繁琐。
将对象序列化为字节序列后,默认会将该对象的整个对象图进行序列化,再通过反序列即可完美地实现深拷贝。
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;public class ObSriaInOut {public static void main(String[] args) throws IOException, ClassNotFoundException{Persen p=in();Persen p2=out();System.out.println(p);System.out.println(p2); }public static Persen out() throws IOException, FileNotFoundException {//創建對象輸出流,在使用對象輸出流時候必須進行對象序列化,否知會報錯java.io.NotSerializableExceptionObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("f:\\person.bin",false));//創建一個persn對象Persen p = new Persen("張大",22,5000);//寫出對象流oos.writeObject(p);//關閉流oos.flush();oos.close();return p;}public static Persen in() throws IOException, FileNotFoundException, ClassNotFoundException {//創建對象輸入流ObjectInputStream ois=new ObjectInputStream(new FileInputStream("f:\\person.bin"));//讀取對象流Persen p=(Persen) ois.readObject();ois.close();System.out.println(p.toString());return p;}}//persen类
package com.javabase.obj.serializable;import java.io.Serializable;public class Persen implements Serializable{private String name;private double sal;private int age;public Persen() {super();}//構造方法用於初始化成員參數public Persen(String name, double sal, int age) {super();this.name = name;this.sal = sal;this.age = age;}@Overridepublic String toString() {return this.name+"---"+this.age+"---"+this.sal;}}