java的clone方法

2019-11-29  本文已影响0人  程序员的交流电

在阿里的java开发手册里面,有这样的一条建议,慎重的使用Object的Clone方法,这个方法是native方法,底层的实现是浅拷贝,那是什么是浅拷贝呢,指的是,当你的要clone的类的里面有自定义的bean,使用clone方法拷贝,改变这个bean的里面的一些属性,也会影响到拷贝出来的对象。这个就是浅拷贝,如果想使用clone实现生拷贝,就要使用深度遍历是拷贝

浅拷贝
public class Title implements Serializable {
//省略getset 和tostring
    private String title;
    public Title(String title) {
        this.title = title;
    }
}
public class Book implements Cloneable {
    private String name;
    private int age;
    private Title title;
//省略getset方法
    public Book(String name, int age, Title title) {
        this.name = name;
        this.age = age;
        this.title=title;
    }
public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    public static void main(String[] args) throws CloneNotSupportedException {
        Title title = new Title("test1");
        Book book = new Book("hhhh", 12, title);
        Book clone = (Book)book.clone();
        System.out.println(book);
        System.out.println(clone);
        System.out.println(book.getTitle());
        book.getTitle().setTitle("test2");
        System.out.println(clone);
    }
}
结果
Book{name='hhhh', age=12, title=Title{title='test1'}}
Book{name='hhhh', age=12, title=Title{title='test1'}}
Title{title='test1'}
Book{name='hhhh', age=12, title=Title{title='test2'}}
深拷贝

需要引用依赖

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.8.1</version>
</dependency>

作者:happyjava
链接:https://juejin.im/post/5d425230f265da039519d248
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
public class Title implements Cloneable{

    private String title;

    public Title(String title) {
        this.title = title;
    }
public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public Object clone() throws CloneNotSupportedException {
        Book newBook = (Book) super.clone();
        newBook.title = (Title) this.title.clone();
        return newBook;
    }
结果
Book{name='hhhh', age=12, title=Title{title='test1'}}
Book{name='hhhh', age=12, title=Title{title='test1'}}
Title{title='test1'}
Book{name='hhhh', age=12, title=Title{title='test1'}}

这里如果要类具有clone的能力还要实现Cloneable接口,这个接口和Serializable一样,没有抽象方法,是一个标志类。否则会报错java.lang.CloneNotSupportedException
Object里面的clone是proteceted修饰的,所以,我们在重写这个方法的时候,注意修饰符要是proteceted或者是public

使用序列化来实现clone

除了使用java提供的clone方法来实现clone,也是使用序列化来实现clone的。

public static void main(String[] args) throws CloneNotSupportedException {
        Book book = new Book();
        book.setName("hhhh");
        book.setAge(100);
        Title title = new Title("test");
        book.setTitle(title);
        System.out.println(book);
        byte[] serialize = SerializationUtils.serialize(book);
        Book deserialize = SerializationUtils.deserialize(serialize);
        System.out.println(deserialize==book);
        System.out.println(deserialize.getTitle()==book.getTitle());

    }
打印结果
Book{name='hhhh', age=100, title=Title{title='test'}}
false
false

一般在面试当中,考java基础的时候,会考到clone的这个知识点,要抓住一下的几点
1,Object的clone是浅拷贝
2,什么是浅拷贝和深拷贝
3,java实现深拷贝的常用两种方法,一个是深度遍历测试,比较麻烦,另外一个是序列化实现。

上一篇 下一篇

猜你喜欢

热点阅读