java clone 浅拷贝 和 深拷贝

java

默认浅拷贝

如果使用clone()方法想要实现深拷贝 必须在实体类中每一个其他内部类对象中实现Cloneable接口,并且重写clone方法

如下:

觉得麻烦可以读到流里再读出来:

package com.fwz.tproject;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.io.Serializable;

import org.junit.Test;

import lombok.Data;

public class CloneTest1 implements Serializable {
@Data
public class Person implements Serializable, Cloneable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private Integer age;
private Address address;

public Object deepClone() throws IOException, OptionalDataException, ClassNotFoundException {
// 将对象写到流里
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
// 从流里读出来
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return (oi.readObject());
}

@Override
protected Object clone() throws CloneNotSupportedException {
Person p = (Person) super.clone();
p.address = (Address) p.address.clone();
return p;
}
}

@Data
public class Address implements Serializable, Cloneable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String type;
private String value;

@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

@Test
public void testShallowCopy() throws Exception {
Address address = new Address();
address.setType("Home");
address.setValue("北京");

Person p1 = new Person();
p1.setAge(31);
p1.setName("Peter");
p1.setAddress(address);

Person p2 = (Person) p1.deepClone();
System.out.println(p1 == p2);// false
p2.setAge(44);
p2.getAddress().setType("Office");
System.out.println("p1=" + p1);
System.out.println("p2=" + p2);
}

@Test
public void testShallowCopy2() throws Exception {
Address address = new Address();
address.setType("Home");
address.setValue("北京");

Person p1 = new Person();
p1.setAge(31);
p1.setName("Peter");
p1.setAddress(address);

Person p2 = (Person) p1.clone();
System.out.println(p1 == p2);// false
p2.setAge(44);
p2.getAddress().setType("Office");
System.out.println("p1=" + p1);
System.out.println("p2=" + p2);
}

}

 

输出:

false

p1=CloneTest1.Person(name=Peter, age=31, address=CloneTest1.Address(type=Home, value=北京))

p2=CloneTest1.Person(name=Peter, age=44, address=CloneTest1.Address(type=Office, value=北京))

原型模式的应用场景

Spring 中bean 的scope 属性的声明:

<bean />

spring 默认scope 是单例模式,这样只会创建一个Action对象,每次访问都是同一个Action对象,数据不安全,struts2 是要求每次次访问都对应不同的Action,scope="prototype" 可以保证 当有请求的时候 都创建一个Action对象。

public class ProtoType {

public static void main(String[] args) {

// TODO Auto-generated method stub

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");

// 获取monster[通过id获取monster]

Object bean = applicationContext.getBean("student");

System.out.println("bean:" + bean);

Object bean2 = applicationContext.getBean("student");

System.out.println("bean1" + bean2);

System.out.println(bean == bean2);

}

}

```

运行结果

bean:com.atguigu.spring.bean.Student@52bf72b5
bean1com.atguigu.spring.bean.Student@37afeb11
false

以上是 java clone 浅拷贝 和 深拷贝 的全部内容, 来源链接: utcz.com/z/394052.html

回到顶部