精华内容
下载资源
问答
  • Java中将一个对象数据复制到另一个对象
    千次阅读
    2021-03-23 17:32:31
    import org.springframework.beans.BeanUtils;
    
    //将User对象中的数据映射到newUser 中
    User newUser = new User();
    BeanUtils.copyProperties(user, newUser);

     

    更多相关内容
  • NULL 博文链接:https://ollevere.iteye.com/blog/1323205
  • 传统上,通过在对象之间复制数据的手动编码值对象汇编器(或转换器)解决了数据对象之间的映射问题。 大多数程序员将开发某种自定义映射框架,并花费无数小时和成千上万行代码映射其不同的数据对象或从其映射...
  • 今天工作时遇到这样一个问题。类B继承类A。从一个方法中得到的返回值的类型是A,然而我要显示在界面中需要的是类B。代码段1如下:public class A{private String s;}public class B extends A{private int i;}...

    今天工作时遇到这样一个问题。类B继承类A。从一个方法中得到的返回值的类型是A,然而我要显示在界面中需要的是类B。

    代码段1如下:

    public class A{

    private String s;

    }

    public class B extends A{

    private int i;

    }

    private A someMethod(){

    A a = new A();

    a.setS("Hello World");

    return a;

    }

    那么问题来了,如何把对象a的成员们的值复制到对象b的同名成员中呢?

    当时首先想到的就是用cast。比如下面这样

    代码段2:

    A aa = someMethod();

    B bb = new B();

    bb = (B) aa;

    这段代码在编译时是没有问题的。但是在运行时就会抛出异常如下:

    java.lang.ClassCastException

    为什么呢?

    在java中使用cast是一定要小心的。使用bb = (B) aa;这种类型转换相当于告诉java,相信我没错的,哥很专业,aa一定是类B,不会有问题的。

    然而事实上aa并不是B。

    从内存的角度上讲(如图1),我们首先定义了aa,其中有一个成员 s("Hello World")。而后我们定义类bb,其有一个成员s(null),及一个成员i(0)。

    最后我们尝试给bb赋值,将其指向堆内存中的aa。然而bb中的i本来指向堆内存中的一个1,在我们将bb指向aa的堆内存地址时,i无所适从,因为aa的堆内存地址中不存在i的位置。

    所以bb = (B) aa; 一定会抛出异常。

    2ecc85be00ad

    图1

    如何解决这个问题?如何把aa里已经存在的值赋值到bb中呢?

    方法1: copyProperties(Object source,Object target)

    在我的项目里我们用了spring,其中有个一类,BeanUtils,其有一个方法copyProperties(),它可以把所有匹配的成员复制。

    代码如下:

    A aa = someMethod();

    B bb = new B();

    BeanUtils.copyProperties(aa, bb);

    这个方法并不需要一定是子类与父类的赋值,只要有同名的成员变量即可。

    方法2: 利用constructor()

    首先在A类中写一个constructor

    public class A {

    private String s;

    public A(String s) {

    this.s = s;

    }

    }

    然后在B类中使用A的构造方法。

    public class B extends A{

    public B(A a) {

    super(a.getS());

    }

    private int i;

    }

    A aa = someMethod();

    B bb = new B(aa);

    bb.setI(1);//this works

    方法3: 利用mapper手动赋值

    这个方法比较简单就不写sample了。

    Ps:技术层面的不足欢迎指出,我一定理清并且改正。

    Ps:如果有人看的话。

    展开全文
  • 今天翻项目中导出报表功能的时候,发现经常复制对象的方法:BeanUtils.copyProperties;把源对象的属性值赋值给目标对象,Spring和Apache和其他的一些框架都给我们提供了对象属性的拷贝方法:org.springframework....

    Spring生态在Java项目中被广泛应用,从架构到技术应用再到常用的基本功能,Spring给我们的开发带来了很大的便利。今天翻到项目中导出报表功能的时候,发现经常复制对象的方法:

    BeanUtils.copyProperties;

    把源对象的属性值赋值给目标对象,Spring和Apache和其他的一些框架都给我们提供了对象属性的拷贝方法:

    org.springframework.beans.BeanUtils.copyProperties(Object source, Object target)

    org.apache.commons.beanutils.BeanUtils.copyProperties(Object dest, Object orig)

    使用的时候注意这两个方法的参数顺序,源和目标是相反的。这两个方法底层都用到了反射,心血来潮之下我自己造了一个对象拷贝的轮子,代码如下:

    importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjava.text.ParseException;importjava.text.SimpleDateFormat;importjava.util.HashMap;public classObjConvertor {private static HashMap> mapSetMethods=new HashMap>();private static HashMap> mapGetMethods=new HashMap>();static{

    }public static booleanConvert(Object src,Object dst) {

    HashMap mapSrc=new HashMap();

    HashMap mapDst=new HashMap();if(mapGetMethods.containsKey(src.getClass().getTypeName()))

    mapSrc=mapGetMethods.get(src.getClass().getTypeName());else{

    Method srcMethods[]=src.getClass().getMethods();

    mapGetMethods.put(src.getClass().getTypeName(),mapSrc);for(Method method:srcMethods)

    {

    String name=method.getName();if(name.startsWith("get"))

    {

    String prop=name.substring(3).toLowerCase();

    mapSrc.put(prop, method);

    }

    }

    }if(mapSetMethods.containsKey(dst.getClass().getTypeName()))

    mapDst=mapSetMethods.get(dst.getClass().getTypeName());else{

    Method dstMethods[]=dst.getClass().getMethods();

    mapSetMethods.put(dst.getClass().getTypeName(),mapDst);for(Method method:dstMethods)

    {

    String name=method.getName();if(name.startsWith("set"))

    {

    String prop=name.substring(3).toLowerCase();

    mapDst.put(prop, method);

    }

    }

    }for(String prop:mapSrc.keySet())

    {if(mapDst.containsKey(prop)){

    Method setMethod=mapDst.get(prop);

    Method getMethod=mapSrc.get(prop);try{

    Object data=getMethod.invoke(src);if(data==null)continue;if(data instanceofjava.sql.Time)

    {if(setMethod.getParameterTypes()[0]==String.class)

    data=data.toString();

    }else if(data instanceofjava.sql.Date)

    {if(setMethod.getParameterTypes()[0]==String.class)

    data=new SimpleDateFormat("yyyy-MM-dd").format(data);

    }else if(data instanceofjava.util.Date)

    {if(setMethod.getParameterTypes()[0]==String.class)

    data=new SimpleDateFormat("yyyy-MM-dd").format((java.util.Date)data);

    }else if(data instanceofjava.sql.Timestamp)

    {if(setMethod.getParameterTypes()[0]==String.class)

    data=data.toString();

    }if(setMethod.getParameterTypes()[0]==java.sql.Time.class)

    {if(data instanceofString)

    data=java.sql.Time.valueOf((String)data);

    }else if(setMethod.getParameterTypes()[0]==java.sql.Date.class)

    {if(data instanceofString)

    data=java.sql.Date.valueOf((String)data);

    }else if(setMethod.getParameterTypes()[0]==java.util.Date.class)

    {if(data instanceofString)

    {

    data=(new SimpleDateFormat("yyyy-MM-dd")).parse((String)data);

    }

    }else if(setMethod.getParameterTypes()[0]==java.sql.Timestamp.class)

    {if(data instanceofString)

    data=java.sql.Timestamp.valueOf((String)data);

    }if(data==null)continue;

    setMethod.invoke(dst, data);

    }catch(IllegalAccessException e) {//TODO Auto-generated catch block

    e.printStackTrace();return false;

    }catch(IllegalArgumentException e) {//TODO Auto-generated catch block

    e.printStackTrace();return false;

    }catch(InvocationTargetException e) {//TODO Auto-generated catch block

    e.printStackTrace();return false;

    }catch(ParseException e) {//TODO Auto-generated catch block

    e.printStackTrace();return false;

    }

    }

    }return true;

    }

    }

    对象拷贝的功能至此完结,如果项目中需要一些特殊格式的数据,可以考虑自己造轮子,这个就看业务需求了。

    接下来谈谈对象拷贝,如果在拷贝这个对象的时候,只对基本数据类型进行了拷贝,而对引用数据类型只是进行引用的传递,而没有真实的创建一个新的对象,则认为是浅拷贝,比如Spring和Apache的copyProperties和上面自己的拷贝方法。反过来,在对引用数据类型进行拷贝的时候,创建了一个新的对象,并且复制其内的成员变量,则认为是深拷贝。

    通过对比不难发现:深拷贝相当于创建了一个新的对象,只是这个对象的所有内容,都和被拷贝的对象一模一样,即两者的修改是隔离的,相互之间没有影响;而浅拷贝也是创建了一个对象,但是这个对象的某些内容(比如A)依然是被拷贝对象的,即通过这两个对象中任意一个修改A,两个对象的A都会受到影响。

    Spring和Apache的copyProperties都属于浅拷贝,在日常开发中基本可以满足使用了。需要注意的是,在Java开发手册中提到,不建议用Apache的BeanUtils工具类,因为其中有很多的检验、类型转换、日志打印等,实现复杂度高,性能比较差。

    那么如果要实现高性能且安全的深度拷贝呢?深拷贝就是被拷贝对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量,那些引用其他对象的变量将指向被拷贝过的新对象,而不再试原有的那些被引用的对象,就是说,深拷贝把要拷贝的对象所引用的对象都复制了一遍。我觉得最靠谱的深拷贝还是要用序列化后写流的方法,这种方法需要实现Serializable接口,多层拷贝时,引用类型都要实现Serializable接口。代码如下:

    import java.io.*;importjava.util.Date;public classCopyDemo {class User implementsSerializable {private intid;private String username;//用户姓名

    private String sex;//性别

    private Date birthday;//生日

    private String address;//地址

    private Person person; //引用类型

    publicUser myColon(){

    User copy=null;try{

    ByteArrayOutputStream baos= newByteArrayOutputStream();

    ObjectOutputStream oos= newObjectOutputStream(baos);

    oos.writeObject(this);//将流序列化成对象

    ByteArrayInputStream bais = newByteArrayInputStream(baos.toByteArray());

    ObjectInputStream ois= newObjectInputStream(bais);

    copy=(User) ois.readObject();

    }catch(IOException e) {

    e.printStackTrace();

    }catch(ClassNotFoundException e) {

    e.printStackTrace();

    }returncopy;

    }//省略get-set方法代码

    }class Person implementsSerializable {private intid;privateString userName ;private intage ;privateString mobilePhone ;publicPerson(){}public Person(int id,String userName, intage, String mobilePhone) {this.id =id;this.userName =userName;this.age =age;this.mobilePhone =mobilePhone;

    }//省略get-set方法

    }

    }

    在Java语言里深拷贝一个对象,先使对象实现Serializable接口,然后把对象(实际上只是对象的一个拷贝)写到一个流里,再从流里读出来,便可以重建对象。通过代码可以更明显的看到这个过程。把对象写到流里的过程是串行化(Serilization)过程,而把对象从流中读出来是并行化(Deserialization)过程。需要注意的是,需要拷贝的对象可能包含多层引用类型,多层拷贝不仅要将拷贝对象实现序列化接口,引用对象也同样的要实现序列化接口。

    展开全文
  • spring: beanutils.copyproperties将一个对象的数据塞入到另一个对象中(合并对象)它的出现原因:BeanUtils提供对Java反射和自省API的包装。其主要目的是利用反射机制对JavaBean的属性进行处理。我们知道,一个...

    spring: beanutils.copyproperties将一个对象的数据塞入到另一个对象中(合并对象)

    它的出现原因: BeanUtils提供对Java反射和自省API的包装。其主要目的是利用反射机制对JavaBean的属性进行处理。我们知道,一个JavaBean通常包含了大量的属性,很多情况下,对JavaBean的处理导致大量get/set代码堆积,增加了代码长度和阅读代码的难度。

    我有一个Category分类表对象,和一个ProductInfo商品表对象

    我需要的数据格式是(以分类作为基数,分类下面有多条帖子):

    data:[

    {

    "cid":1,

    "name":"灌水",

    "theads":[

    {

    "id":1,

    "cid":1,

    "name":"有喜欢这歌的吗?"

    "time":"2018-12-12 18:25"

    },

    {

    "id":1,

    "cid":1,

    "name":"有喜欢这歌的吗?"

    "time":"2018-12-12 18:25"

    }

    ]

    } ,{

    "cid":2,

    "name":"文学",

    "theads":[

    {

    "id":18,

    "cid":2,

    "name":"徐志摩的诗"

    "time":"2018-12-12 18:25"

    },

    {

    "id":21,

    "cid":2,

    "name":"鲁迅的散文"

    "time":"2018-12-12 18:25"

    }

    ]

    }

    ]

    代码如下

    ResultVO resultVO = new ResultVO();

    //ProductVO productVO = new ProductVO();

    //List productInfoVOList = new ArrayList();

    //productVO.setProductInfoVOList(productInfoVOList);

    //resultVO.setData(productVO);

    //查询商品

    List productInfoList = product.findAll();

    //查询商品类目(一次性读完)

    //传统方法

    // List categoryTypeList = new ArrayList<>();

    //for (ProductInfo productInfo: productInfoList)

    // {

    // categoryTypeList.add(productInfo.getCategoryType());

    //}

    //java8-lambda方法

    List categoryTypeList = productInfoList.stream().map(e -> e.getCategoryType()).collect(Collectors.toList());

    List CategoryList = category.findByCategoryTypeIn(categoryTypeList);

    //拼合数据

    for (ProductCategory category: CategoryList)

    {

    //productCategory

    ProductVO productVO = new ProductVO();

    productVO.setCategoryType(category.getCategoryType());

    productVO.setCategoryName(category.getCategoryName());

    //productInfo

    List productInfoVOList = new ArrayList<>();

    for (ProductInfo productInfo : productInfoList)

    {

    if(productInfo.getCategoryType().equals(category.getCategoryType()))

    {

    //老方法:

    ProductInfoVO productInfoVO = new ProductInfoVO();

    productInfoVO.setProductId(productInfo.getProductId());

    productInfoVO.setProductName(productInfo.getProductName());

    productInfoVOList.add(productInfoVO);

    //新方法:将productInfo属性复制到productInfoVO1中

    //beanutils.copyproperties

    ProductInfoVO productInfoVO1 = new ProductInfoVO();

    BeanUtils.copyProperties(productInfo, productInfoVO1);

    productInfoVOList.add(productInfoVO1);

    }

    }

    productVO.setProductInfoVOList(productInfoVOList);

    }

    return resultVO;

    //return "list";

    展开全文
  • java 对象拷贝相同属性到另一个对象

    千次阅读 2020-11-28 16:54:43
    BeanUtils.copyProperties(对象1,要赋值的对象);
  • 使用反射将所有数据从一个对象复制到另一个对象的 Java 实用程序。 “复制”操作,si 基于现有的 getter 和 setter 完成。 源类和目标类必须具有相同的 getter 和相同的 setter 才能工作。 在我的项目中,我总是...
  • JAVA复制对象另一个对象

    千次阅读 2019-02-24 13:45:55
    JAVA复制对象另一个对象
  • 需求:将对象属性值快速复制到另一个对象上,忽略空值属性和id 直接上代码:BeanUtils 工具类 import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import ...
  • Java对象复制

    千次阅读 2022-02-11 11:26:57
    Java对象复制(拷贝)
  • 如题,这种场景其实项目里使用场景很多,经常需要进行这种对象值的复用,但是又怕使用不准确,影响对象的值。 那么该篇文章介绍一个方法,简单粗暴,就是使用BeanUtils。 简单示例: Dog,里面有两个字段...
  • import org.springframework.beans.BeanUtils; BeanUtils.copyProperties(源对象, 目标对象);
  • java对象赋值给另一个对象

    千次阅读 2021-03-05 19:56:29
    对基本数据类型的赋值很简单的。基本类型存储了实际的数值,而并非指向一个对象的引用,所以在赋值的时候,是...所以倘若“将一个对象赋值给另一个对象“的时候,实际上是将“引用”从一个地方复制到另一个地方。这...
  • import org.springframework.beans.BeanUtils; BeanUtils.copyProperties(源对象, 目标对象);
  • 主要介绍了利用Java反射机制实现对象相同字段的复制操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • Java copy对象的工具类

    2018-07-27 13:47:52
    Java CopyUtil工具类,可以进行对象的深copy,比如:对象里面包含对象对象里面包含Map,List,Set...等复杂类型的属性都可以copy,copy后的对象与原有对象没有联系,即改变原有对象内容,不会改变copy后的对象里面的...
  • 代码: BeanUtils.copyProperties(对象1,对象2); 如此即可把对象1的值赋值给对象2.
  • @Override public ItemsCustom findItemsById(Integer id) throws Exception { Items items = itemsMapper.selectByPrimaryKey(id);... //最终返回的是ItemsCustom的对象类型 ItemsCustom itemsCustom...
  • java对象复制克隆

    2013-10-28 08:52:09
    深度复制Java对象实例,复制后对象属性值改变不影响被复制对象,有注释
  • java中如何快速优雅的把一个对象的属性赋值到另一个对象中(驼峰->驼峰,驼峰->下划线,下划线->驼峰)一、驼峰->驼峰二、驼峰->下划线,下划线->驼峰 在工作中,我们经常会遇到对象之间赋值的...
  • 将数据从一个对象复制到另一个对象使用Spring的BeanUtils在开发中我们常会在对象之间设置属性值:Order order = new Order(); order.setOrderAmount(orderDTO.getOrderAmount()); order.setOrderStatus(orderDTO....
  • 首先导入json相关jar包 Institution institution =institutionService.selectInstitutionById(institutionId); //将企业回显对象转换为json String institutionJson = JSON.toJSONString(institution); //重新赋值...
  • BeanUtils.copyProperties(源对象,目标对象)
  • java中把一个对象赋值给另一个对象结果两个对象变成同一个对象。 但是注意 对于String类型的对象以及Integer(基本类型的封装类)的对象即使把一个对象赋给另一个后是同一个对象,但对其中一个对象赋不同的值...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 575,449
精华内容 230,179
关键字:

java对象复制到另一个对象

java 订阅