胖蔡说技术
随便扯扯

Java 原型模式

原型模式(Prototype Pattern)是归属于创建型模式的一个分支,是通过使用给一个已经创建的实例作为原型,通过复制当前的原型对象来实现创建一个和原型对象相同的新的对象的方式。Java中的原型模式主要可以通过Java提供的clone方法来实现对象的克隆。通过拷贝方式的不同又可分为浅拷贝和深拷贝,如下介绍两种方式的创建和使用的不同。

浅拷贝

浅拷贝是将一个对象复制后,基本数据类型的变量都会重新创建,而数组、容器对象、引用对象等都不会拷贝,指向的还是原对象所指向的地址。浅拷贝实现 Cloneable,重写clone方法。

常用API功能如下:

  • 使用Spring中 BeanUtilsPropertyUtils直接进行对象复制(对于Android端的java代码并不适用)
  • 实现Cloneable接口(推荐使用)
  • Arrays.copyOf(),但在ArrayList中实现了深拷贝的效果

1、创建地址类

/**
 * 地址类
 */
@Data
@Accessors(chain = true)
public class Address {
    private String province;

    private String municipality;

    private String region;

}

2、创建用户类

/**
 * 用户类
 */
@Data
public class User implements Cloneable {
    private String userName;

    private Address address;

    @Override
    protected User clone() {
        try {
            return (User) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

3、使用

public static void main(String[] args) {
    User user1 = new User();
    user1.setUserName("张三");
    user1.setAddress(new Address().setProvince("甘肃省").setMunicipality("兰州市").setRegion("七里河区"));
    User clone = user1.clone();
    System.out.println(user1);
    System.out.println(clone);
    System.out.println(user1 == clone); // false
    System.out.println(user1.getAddress() == clone.getAddress()); // true  引用的同一个对象,修改其中一个用户的地址会影响到另一个用户的地址
}

深拷贝

深拷贝是将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。深拷贝是通过实现 Serializable 读取二进制流。

API使用:

  • 每个对象都需实现Cloneable接口并重写Object中的clone()方法
  • 需要通过实现Serializable接口实现序列化,这也是串口、蓝牙通信常用的方式
  • Apache Commons工具SerializationUtils.clone(T object)功能
  • 通过JSON工具实现数据深拷贝,其原理和Serializable大同小异
  • 通过构造方法实现深拷贝(new对象会给对象创建一个新的地址空间)

1、创建地址类

/**
 * 地址类
 */
@Data
@Accessors(chain = true)
public class Address implements Serializable {
    private String province;

    private String municipality;

    private String region;

}

2、创建用户类

/**
 * 用户类
 */
@Data
public class User implements Cloneable, Serializable {
    private String userName;

    private Address address;

    @Override
    protected User clone() {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            return (User) ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}

3、使用

public static void main(String[] args) {
    User user1 = new User();
    user1.setUserName("张三");
    user1.setAddress(new Address().setProvince("甘肃省").setMunicipality("兰州市").setRegion("七里河区"));
    User clone = user1.clone();
    System.out.println(user1);
    System.out.println(clone);
    System.out.println(user1 == clone);
    System.out.println(user1.getAddress() == clone.getAddress());
}
赞(0) 打赏
转载请附上原文出处链接:胖蔡说技术 » Java 原型模式
分享到: 更多 (0)

请小编喝杯咖啡~

支付宝扫一扫打赏

微信扫一扫打赏