java 原型话设计方法(涉及深拷贝可浅拷贝)

原型化设计模式是一种设计模式,可以简单的理解为克隆模式

首先看一段代码

public class WorldDocument implements Cloneable {
    private String mText;
    private ArrayList<String> mImages = new ArrayList<>();

    public WorldDocument() {
        System.out.println("----- 这个是构造函数-------");
    }

    public String getmText() {
        return mText;
    }
    public void setText(String  text){
        this.mText = text;
    }

    public void setmText(String mText) {
        this.mText = mText;
    }

    public ArrayList<String> getmImages(){
        return this.mImages;
    }
    public void addImage(String img){
        this.mImages.add(img);
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        WorldDocument doc = (WorldDocument) super.clone();
        doc.mText = this.mText;
        doc.mImages = this.mImages;
      //   doc.mImages = (ArrayList<String>) this.mImages.clone();//这样就是深拷贝
        return doc;
    }
    //打印文档的内容
    public void showDocument(){
        System.out.println("--------------word content Start-------------");
        System.out.println("text: "+this.mText);
        System.out.println("Images List: ");
        for (String imgs: mImages) {
            System.out.println("------------: "+imgs);
        }
        System.out.println("--------------word content end-------------");
    }
}

在这里我们写一个类 实现Cloneable这个接口,写两个测试的属性 mText和mImages,在重写clone()这个方法里我们可以看到这样一段代码

WorldDocument doc = (WorldDocument) super.clone();

也就是调用父类的clone方法,注意调用clone()方法形成的实例是不会调用它的构造函数的

测试类

    public static void main(String[] args) throws CloneNotSupportedException {
        WorldDocument world = new WorldDocument();
        world.setText("文字1");
        world.addImage("photo1");
        world.addImage("photo2");
        world.addImage("photo3");
        WorldDocument document2 = (WorldDocument) world.clone();
        document2.showDocument();
        world.showDocument();

    }

测试结果

这里写图片描述

可以很明显的看到两个对象是完全一样的。下面我们稍作修改

    public static void main(String[] args) throws CloneNotSupportedException {
        WorldDocument world = new WorldDocument();
        world.setText("文字1");
        world.addImage("photo1");
        world.addImage("photo2");
        world.addImage("photo3");
        WorldDocument document2 = (WorldDocument) world.clone();
        world.setText("修改的文字");
        world.addImage("添加的照片");
        document2.showDocument();
        world.showDocument();

    }

再看打印的结果

这里写图片描述
我们很奇怪的发现了对源文件进行修改的时候只有数组变化,但是文字变量并没有改变,这是为什么呢。这里就涉及到浅拷贝可深拷贝的问题,在这里给大家很简单的说下,如果有兴趣
可以深入的研究这个问题。
浅拷贝可深拷贝 : 浅拷贝是简单的拷贝地址,就像C++里面的指针指针类似,而深拷贝是完全的拷贝,是拷贝堆里面的内容,所以浅拷贝的时候拷贝的内容受源内容影响。

想必说到这里,有人就感觉以后,对面上面的例子好像不是那么回事,其实上面的mText是一个变量,不是引用,所以它不存在浅拷贝和深拷贝问题。而数组就不一样了,数组拷贝的就是栈里面的地址,并没有完全的拷贝对立面的内容,所以源对象改变的时候,拷贝的对象也会随之改变。那么怎么进行深拷贝呢?

使用在源对象中就进行深拷贝的操作

doc.mImages = (ArrayList<String>) this.mImages.clone();//这样就是深拷贝

使用这个之后我们可以再来看下打印的结果
这里写图片描述

使用完之后我们就会发现,这两个对象之间没有任何联系,是单独的两个对象,这也就是深拷贝的结果。

猜你喜欢

转载自blog.csdn.net/jeekmary/article/details/80958334