文章《用Spring的BeanUtils前,建议你先了解这几个坑》里面,作者最后得到了这几个结论:

1.Spring得BeanUtils得CopyProperties方法需要对应得属性有getter和setter方法;

2.如果存在属性完全相同得内部类,但是不是同一个内部类,即分别属于各自得内部类,则Spring会认为属性不同,不会Copy;

3.泛型只在编译期起作用,不能依靠泛型来做运行期得限制;

4.最后,Spring和Apache得copy属性得方法源和目的参数得位置正好相反,所以导包和调用得时候需要注意以下。

在这里,我们今天重点说的是第二点,第一点是因为用反射拿到set和get方法再去拿属性值和设置属性值的,不懂反射的人可以自行百度下。第三和第四点很简单了应该是不需要解释的。

验证

首先,我把我自己的测试代码也贴出来:

@Data

public class TestEntity{

private Integer age;

private String name;

private Inner inner;

@Data
public static class Inner{
private Integer a;
public Inner(Integer a){
this.a = a;
}
}

}

@Data

public class TestVO{

private Integer age;

private String name;

private Inner inner;

@Data
public static class Inner{
private Integer a;
public Inner(Integer a){
this.a = a;
}
}

}

public class Main{

public static void main(String args[]){

TestEntity entity = new TestEntity();

entity.setAge(1);

entity.setName("hehe");

entity.setInner(new TestEntity.Inner(1));

    TestVO vo = new TestVO();
BeanUtils.copyProperties(entity,vo);
System.out.println(vo.toString()); }

}

以上就是我得三个类,是不是超级简单,比如工作中将entity转vo,就有这种使用场景,运行main方法,测试结果和那个作者得出的第二点的结论是一样的,b对象里面的inner是null!



但是这个是为什么呢?这个是BUG吗?这个也是我今天要说的重点。

内部类

我们知道,java给我们提供了内部类这样的东东,但是java的内部类,它其实只是java的一个语法糖而已(不知道什么是语法糖的请自行百度),那么我们定义得两个JAVA类里面的Inner的真面目到底是怎样的呢?

来到编译后的.class文件目录下,我们可以看到编译后得.class文件:



哈哈,不知道读者到这里是不是能明白些什么了呢?为什么经过BeanUtils.CopyProperties(entity,vo)之后,vo里面的inner还是null,因为TestEntity.java和TestVO.java里面的Inner在编译之后的class名字都不一样(代表加载到虚拟机之后的地址不同),怎么可能拷贝成功呢?

那么问题来了哈,我们怎样用才能让其拷贝成功呢?我稍微修改了下我的代码如下:

@Data

public class TestVO{

private Integer age;

private String name;

private TestEntity.Inner inner;

}

仅仅是把Inner变为了TestEntity.Inner,删掉了没引用得内部类Inner,Main.java不变,然后运行结果如下:



可以看到,b对象里面的inner被成功拷贝过来。

此时编译后得class文件也由5个变为了4个

关于Spring的BeanUtils的更多相关文章

  1. 关于Spring中BeanUtils的一次使用问题记录

    1.问题描述:今天在进行前后端联调的时候,发现商品图片不能正常显示: 2.排查过程:查看浏览器控制台,发现调用接口返回的数据关于图片的字段未返回数据:      然后,又跑了一下Dao层的单元测试,从 ...

  2. Spring中的BeanUtils与apache commons中的BeanUtils用法[1]

    1. 前言 在开发过程中,经常遇到把要给一个bean的属性赋给另外一个bean.最笨的方法是每个属性都单独写一个,聪明的方法是应用反射写一个工具方法.考虑到这个需求基本每个程序员都会遇到,那么一定已经 ...

  3. spring BeanUtils 工具实现对象之间的copy

    一般我们会开发中会遇到返回用户信息的时候,不需要返回密码或者其他参数,这时候我们需要重新定义一个VO类去除不需要的参数,将原对象copy到VO类中 使用spring的BeanUtils可以实现对象的c ...

  4. Bean复制的几种框架性能比较(Apache BeanUtils、PropertyUtils,Spring BeanUtils,Cglib BeanCopier)

    转自:http://www.cnblogs.com/kaka/archive/2013/03/06/2945514.html 比较的是四种复制的方式,分别为Apache的BeanUtils和Prope ...

  5. 基于 asm 实现比 spring BeanUtils 性能更好的属性拷贝框架

    Bean-Mapping 日常开发中经常需要将一个对象的属性,赋值到另一个对象中. 常见的工具有很多,但都多少不够简洁,要么不够强大. 我们经常使用的 Spring BeanUtils 性能较好,但是 ...

  6. Bean映射工具之Apache BeanUtils VS Spring BeanUtils

    背景 在我们实际项目开发过程中,我们经常需要将不同的两个对象实例进行属性复制,从而基于源对象的属性信息进行后续操作,而不改变源对象的属性信息,比如DTO数据传输对象和数据对象DO,我们需要将DO对象进 ...

  7. Apache BeanUtils与Spring BeanUtils性能比较

    在我们实际项目开发过程中,我们经常需要将不同的两个对象实例进行属性复制,从而基于源对象的属性信息进行后续操作,而不改变源对象的属性信息,比如DTO数据传输对象和数据对象DO,我们需要将DO对象进行属性 ...

  8. BeanUtils.copyProperties() 用法--部分转

    把一个类对象copy到另一个类对象(这两个可以不同). 1.org.apache.commons.beanutils.BeanUtils.copyProperties(dest, src) org.s ...

  9. BeanUtils.copyProperties缓解代码压力,释放双手

    简单描述:之前在写代码的时候,经常把表单提交到后台的对象的参数,通过getter方法取出来,然后,再通过setter方法传递给需要的对象,代码中写了很多get set这种方法,后来听同事说,sprin ...

随机推荐

  1. Docker清除容器镜像命令:

    # ~/.bash_aliases # Kill all running containers. alias dockerkillall='docker kill $(docker ps -q)' # ...

  2. metal cmd执行时间

    https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/MTLBestPracticesGuide ...

  3. Idea中Module is not specified解决办法

    打开idea,想跑一个类,但是,给我报了一个红叉: 当我点击run的时候,弹出来一个框: “Error:Module not specified”  Module 未指定 “这个原因是项目文件夹有修改 ...

  4. CSS实现按钮YES-NO按钮+Jquery获取按钮状态。

    前几天我经理突然跟我说,能不能做一个开关按钮,需要过滤的一个标识.说实话,一个做后端我是懵逼状态的. 不过网上资料很多,查了一遭,发现一个不错的哥们给出的案例,模仿一下成功实现,下面就自己总结一下: ...

  5. C# ado.net 使用task和await(四)

    class Program { private static string constr = "server=.;database=northwnd;integrated security= ...

  6. 使用laravel-wechat微信支付

    参考文档 https://github.com/overtrue/laravel-wechat https://easywechat.com/docs/4.1/payment/index larave ...

  7. 微软企业库Unity依赖注入

    Unity Application Block 1.0系列(4): 方法调用注入(Method Call Injection ) http://www.cnblogs.com/inrie/archiv ...

  8. Go中&和*的区别

    & 返回变量的内存地址 * 返回变量的值, * 只能作用在指针上 package main import "fmt" func main() { var a = 5 var ...

  9. Mybatis源码学习之日志(五)

    简述 在Java开发中常用的日志框架有Log4j.Log4j2.Apache Commons Log.java.util.logging.slf4j等,这些工具对外的接口并不相同.为了统一这些工具的接 ...

  10. [CSP-S模拟测试]:B(期望DP)

    题目传送门(内部题151) 输入格式 第一行一个整数$N$. 第二行$N$个整数,第$i$个为$a_i$. 输出格式 一行一个整数,表示答案.为避免精度误差,答案对$323232323$取模. 即设答 ...