对象拷贝
项目开发过程中很多时候需要进行对象复制,可是有的时候会发生复制后的对象,在原对象改变后也相应发生改变,这种时候就有问题了。所以很有必要了解对象的深拷贝,以及深拷贝的几种方式。
new 对象
手动 new 新的对象,一个属性一个属性的赋值,这种方式比较原始,也比较繁琐,容易出错,直接略过。
重载 clone()方法
对象中的基本类型是不需要考虑深拷贝的,深拷贝只针对对象类型或者对象集合对象。对于这种,可以分别重载对象中的clone方式
示例: OrderVO有三个字段
// (基本类型)
private String orderNo;
// (对象类型)
private UserVo userVo;
// (对象集合类型)
private List<GoodsVO> goodsVoList;
OrderVo
package test.copy.vo;
import java.util.ArrayList;
import java.util.List;
public class OrderVO implements Cloneable{
private String orderNo;
private UserVO userVO;
private List<GoodsVO> goodsVOList;
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public UserVO getUserVO() {
return userVO;
}
public void setUserVO(UserVO userVO) {
this.userVO = userVO;
}
public List<GoodsVO> getGoodsVOList() {
return goodsVOList;
}
public void setGoodsVOList(List<GoodsVO> goodsVOList) {
this.goodsVOList = goodsVOList;
}
@Override
public OrderVO clone() {
try {
OrderVO orderVO = (OrderVO) super.clone();
orderVO.setUserVO(this.userVO.clone());
if (goodsVOList != null && goodsVOList.size() > 0) {
List<GoodsVO> goodsList = new ArrayList<>();
for (GoodsVO goodsVO : goodsVOList) {
goodsList.add(goodsVO.clone());
}
orderVO.setGoodsVOList(goodsList);
}
return orderVO;
} catch (CloneNotSupportedException e) {
System.out.println("exception happened");
}
return null;
}
}
UserVo
package test.copy.vo;
public class UserVO implements Cloneable{
private String userName;
private int age;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public UserVO clone() {
try {
UserVO userVO = (UserVO) super.clone();
return userVO;
} catch (CloneNotSupportedException e) {
System.out.println("exception happened");
}
return null;
}
}
GoodsVo
package test.copy.vo;
import java.math.BigDecimal;
public class GoodsVO implements Cloneable{
private String goodsName;
private BigDecimal price;
public String getGoodsName() {
return goodsName;
}
public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
@Override
public GoodsVO clone() {
try {
GoodsVO userVO = (GoodsVO) super.clone();
return userVO;
} catch (CloneNotSupportedException e) {
System.out.println("exception happened");
}
return null;
}
}
测试类
package test.copy.vo;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class TestCopy {
public static void main(String[] args) {
OrderVO orderVO = new OrderVO();
orderVO.setOrderNo("T0001001010");
UserVO userVO = new UserVO();
userVO.setUserName("Ellen Max");
userVO.setAge(45);
orderVO.setUserVO(userVO);
List<GoodsVO> goodsVOList = new ArrayList<>();
GoodsVO goodsVO1 = new GoodsVO();
goodsVO1.setGoodsName("迪士尼门票");
goodsVO1.setPrice(new BigDecimal("556"));
GoodsVO goodsVO2 = new GoodsVO();
goodsVO2.setGoodsName("东方明珠门票");
goodsVO2.setPrice(new BigDecimal("125"));
goodsVOList.add(goodsVO1);
goodsVOList.add(goodsVO2);
orderVO.setGoodsVOList(goodsVOList);
OrderVO orderVO1 = orderVO.clone();
System.out.println("clone success");
orderVO.setOrderNo("A000123123");
orderVO.getUserVO().setUserName("Steve Jobs");
orderVO.getGoodsVOList().get(0).setGoodsName("香港迪士尼门票");
System.out.println("改变原始orderVo");
System.out.println("orderVO1.userVo.userName 没有改变");
System.out.println("orderVO1.goodsVOList.get(0).goodsName 没有改变");
}
}
JSON序列号
这种方式比较简单,就是对象转json字符串,再利用JSONObject转成对象,parseObject或者parseArray方法
Apache Commons Lang里面的SerializationUtils
这种方式有两点需要注意
- 类都实现Serializable接口
- 转换需要是同一种类,不通类之间无法转换,否则会报错
OrderDTO
package test.copy.vo;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class OrderDTO implements Serializable {
private String orderNo;
private UserDTO userDTO;
private List<GoodsDTO> goodsDTOList;
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public UserDTO getUserDTO() {
return userDTO;
}
public void setUserDTO(UserDTO userDTO) {
this.userDTO = userDTO;
}
public List<GoodsDTO> getGoodsDTOList() {
return goodsDTOList;
}
public void setGoodsDTOList(List<GoodsDTO> goodsDTOList) {
this.goodsDTOList = goodsDTOList;
}
}
UserDTO
package test.copy.vo;
import java.io.Serializable;
public class UserDTO implements Serializable {
private String userName;
private int age;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
GoodsDTO
package test.copy.vo;
import java.io.Serializable;
import java.math.BigDecimal;
public class GoodsDTO implements Serializable {
private String goodsName;
private BigDecimal price;
public String getGoodsName() {
return goodsName;
}
public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}
Test
package test.copy.vo;
import org.apache.commons.lang3.SerializationUtils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class CommonsLangCopyTest {
public static void main(String[] args) {
OrderDTO orderDTO = new OrderDTO();
orderDTO.setOrderNo("T0001001010");
UserDTO userDTO = new UserDTO();
userDTO.setUserName("Ellen Max");
userDTO.setAge(45);
orderDTO.setUserDTO(userDTO);
List<GoodsDTO> goodsDTOList = new ArrayList<>();
GoodsDTO goodsDTO1 = new GoodsDTO();
goodsDTO1.setGoodsName("迪士尼门票");
goodsDTO1.setPrice(new BigDecimal("556"));
GoodsDTO goodsDTO2 = new GoodsDTO();
goodsDTO2.setGoodsName("东方明珠门票");
goodsDTO2.setPrice(new BigDecimal("125"));
goodsDTOList.add(goodsDTO1);
goodsDTOList.add(goodsDTO2);
orderDTO.setGoodsDTOList(goodsDTOList);
// 不需要指定class类型,因为只能为同一个类
OrderDTO orderDTO1 = SerializationUtils.clone(orderDTO);
System.out.println("clone success");
orderDTO.setOrderNo("A000123123");
orderDTO.getUserDTO().setUserName("Steve Jobs");
orderDTO.getGoodsDTOList().get(0).setGoodsName("香港迪士尼门票");
System.out.println("change source attribute");
}
}
使用TypeReference
这个可以将任意json字符串转成成任意形式,如
- 对象
- List对象
- Map<String, List>
// 字符串转List<Object>
List<ActuaryAssessmentReqDTO.Drug> drugList = JSONObject.parseObject(JSONObject.toJSONString(obj), new TypeReference<List<ActuaryAssessmentReqDTO.Drug>>() {});
// 字符串转HashMap<String, List<List<ErrorInfo>>>
Map<String, List<List<ErrorInfo>>> resultInfo = JSONObject.parseObject(obj, new TypeReference<HashMap<String, List<List<ErrorInfo>>>>() {});