美文网首页
Java浅拷贝 深拷贝

Java浅拷贝 深拷贝

作者: 一个小草人 | 来源:发表于2019-12-09 09:56 被阅读0次

    在Java中,除了基本数据类型之外,还存在引用类型,在方法参数传递时,对于基本数据类型,实际上是值传递,引用类型则是地址传递,将原对象的引用传递过去,他们实际上还是指向同一个对象,String是一种特殊的引用类型,有些值类型的样子,,使得它也相当于值传递。
    而浅拷贝和深拷贝就是在这个基础之上做的区分,如果在拷贝这个对象时,只对基本数据类型、String进行了拷贝,而对引用数据类型只是进行了引用的传递,而没有真实的创建一个新的对象,则认为是浅拷贝。反之,再对引用数据类型进行拷贝的时候,创建了一个新的对象,而且复制其内的成员变量,则认为是深拷贝。
    所以所谓的浅拷贝和深拷贝,只是在拷贝对象的时候,对类的实例对象这种引用数据类型的不同操作而已。

    • 浅拷贝:对基本数据类型进行值拷贝,引用数据类型只是引用地址拷贝,此为浅拷贝


      image.png
    • 深拷贝:对基本数据类型进行值拷贝,引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝


      image.png

    下面是一个深拷贝的例子

    //Cloneable 接口,可以看到它其实什么方法都不需要实现。对他可以简单的理解只是一个标记,是开发者允许这个对象被拷贝。
    public class Person implements Cloneable {
        public int age;
        public String name;
        public List<String> hobbyList;
        public List<Book> bookList;
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            //super.clone()浅拷贝,使得age、name完成了值拷贝
            Person p = (Person) super.clone();
            //hobbyList、bookList为引用类型,需要进行深度拷贝
            //List<String>只需要完成浅拷贝即可
            p.hobbyList = (List<String>) ((ArrayList<String>) hobbyList).clone();
            List<Book> books = new ArrayList<>();
            for (Book book : bookList) {
                books.add((Book) book.clone());
            }
            p.bookList = books;
            return p;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "age=" + age +
                    ", name='" + name + '\'' +
                    ", hobbyList=" + hobbyList +
                    ", bookList=" + bookList +
                    '}';
        }
    }
    
    public class Book implements Cloneable {
        public String bookName;
        public float price;
    
        public Book(String bookName, float price) {
            this.bookName = bookName;
            this.price = price;
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            //String、float不需要进行深度拷贝
            return super.clone();
        }
    
        @Override
        public String toString() {
            return "Book{" +
                    "bookName='" + bookName + '\'' +
                    ", price=" + price +
                    '}';
        }
    }
    
    public class Test {
    
        public static void main(String[] args) {
            Person p = new Person();
            p.name = "小红";
            p.age = 10;
            p.hobbyList = new ArrayList<>();
            p.hobbyList.add("旅游");
            p.hobbyList.add("跑步");
            p.bookList = new ArrayList<>();
            p.bookList.add(new Book("追忆似水年华", 80.0f));
            p.bookList.add(new Book("悲惨世界", 66.0f));
    
            //对Person p进行深度拷贝
            Person pCopy = null;
            try {
                pCopy = (Person) p.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            pCopy.name = "小明";
            pCopy.age = 15;
            pCopy.hobbyList.set(0, "读书");
            pCopy.bookList.set(0, new Book("简爱", 50.0f));
    
            System.out.println(p.toString());
            System.out.println(pCopy.toString());
    
        }
    
    }
    

    相关文章

      网友评论

          本文标题:Java浅拷贝 深拷贝

          本文链接:https://www.haomeiwen.com/subject/nhvdgctx.html