BeanUtils工具类中的copyProperties方法使用

1.两个包下的BeanUtils.copyProperties对比

BeanUtils是开发中常用到的工具类,通过导入org.springframework.beans.BeanUtils或者org.apache.commons.beanutils.BeanUtils包来获取,但是不同的包中BeanUtils的方法使用是不一样的,接下来对这两个包中的copyProperties方法进行对比。

typescript 复制代码
//org.springframework.beans.BeanUtils
public static void copyProperties(Object source, Object target){....}

//org.apache.commons.beanutils.BeanUtils
public static void copyProperties(Object dest,Object orig){....}

由定义可知,在org.springframework.beans.BeanUtils包下第一个参数是被copy的对象,而org.apache.commons.beanutils.BeanUtils中却是第二个参数,使用时不要弄混。

1)接下来定义两个实体类Student和Teacher,来模拟目标对象中包含被copy的对象所有字段时。

typescript 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private String id;
    private String name;
    private String age;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
    private String id;
    private String name;
    private String age;
    private String sex;   //多出来的参数
}

先用org.springframework.beans.BeanUtils下的copyProperties来进行测试,执行代码如下:

ini 复制代码
public class Test {
    public static void main(String[] args) {
        Student student = new Student(UUID.randomUUID().toString(), "wx", "22");
        Teacher teacher = new Teacher();
        System.out.println(student);
        BeanUtils.copyProperties(student,teacher);
        System.out.println(teacher);
    }
}

执行结果如下:
Student(id=c467e774-022d-4ada-9212-5d199da2558a, name=wx, age=22)
Teacher(id=c467e774-022d-4ada-9212-5d199da2558a, name=wx, age=22, sex=null)

当将引入的包改为org.apache.commons.beanutils.BeanUtils时,将上述中的执行代码进行如下修改:

scss 复制代码
BeanUtils.copyProperties(teacher,student); //因为apache包下被copy的参数在第二个位置

执行结果如下:
Student(id=900d0b93-1913-4022-b86b-127682cd9f5c, name=wx, age=22)
Teacher(id=00c47e77-785d-4939-89db-e757979050ec, name=wx, age=22, sex=null)

小结:当目标对象(target/dest)中包含被copy的对象(source/orig)的所有字段时,两种包下的copyProperties方法均可以执行成功。

2)对上述的实体类进行修改,即目标对象中不包含被copy对象的所有字段时,修改内容如下:

less 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private String id;
    private String name;
    private String age;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
    private String id;
    private String name;
}

执行代码与1)中一样,先使用org.apache.commons.beanutils.BeanUtils中的copyProperties方法,执行结果如下:

less 复制代码
Student(id=125d6364-524b-407c-a426-9d7dfc078305, name=wx, age=22)
11:28:31.604 [main] DEBUG org.apache.commons.beanutils.converters.BooleanConverter - Setting default value: false
11:28:31.607 [main] DEBUG org.apache.commons.beanutils.converters.BooleanConverter - Converting 'Boolean' value 'false' to type 'Boolean'
11:28:31.607 [main] DEBUG org.apache.commons.beanutils.converters.BooleanConverter -     No conversion required, value is already a Boolean
11:28:31.610 [main] DEBUG org.apache.commons.beanutils.converters.ByteConverter - Setting default value: 0
11:28:31.610 [main] DEBUG org.apache.commons.beanutils.converters.ByteConverter - Converting 'Integer' value '0' to type 'Byte'
11:28:31.610 [main] DEBUG org.apache.commons.beanutils.converters.ByteConverter -     Converted to Byte value '0'
11:28:31.611 [main] DEBUG org.apache.commons.beanutils.converters.CharacterConverter - Setting default value:  
11:28:31.611 [main] DEBUG org.apache.commons.beanutils.converters.CharacterConverter - Converting 'Character' value ' ' to type 'Character'
11:28:31.611 [main] DEBUG org.apache.commons.beanutils.converters.CharacterConverter -     No conversion required, value is already a Character
11:28:31.611 [main] DEBUG org.apache.commons.beanutils.converters.DoubleConverter - Setting default value: 0
11:28:31.611 [main] DEBUG org.apache.commons.beanutils.converters.DoubleConverter - Converting 'Integer' value '0' to type 'Double'
11:28:31.611 [main] DEBUG org.apache.commons.beanutils.converters.DoubleConverter -     Converted to Double value '0.0'
11:28:31.612 [main] DEBUG org.apache.commons.beanutils.converters.FloatConverter - Setting default value: 0
11:28:31.612 [main] DEBUG org.apache.commons.beanutils.converters.FloatConverter - Converting 'Integer' value '0' to type 'Float'
11:28:31.612 [main] DEBUG org.apache.commons.beanutils.converters.FloatConverter -     Converted to Float value '0.0'
11:28:31.612 [main] DEBUG org.apache.commons.beanutils.converters.IntegerConverter - Setting default value: 0
11:28:31.612 [main] DEBUG org.apache.commons.beanutils.converters.IntegerConverter - Converting 'Integer' value '0' to type 'Integer'
11:28:31.612 [main] DEBUG org.apache.commons.beanutils.converters.IntegerConverter -     No conversion required, value is already a Integer
11:28:31.613 [main] DEBUG org.apache.commons.beanutils.converters.LongConverter - Setting default value: 0
11:28:31.613 [main] DEBUG org.apache.commons.beanutils.converters.LongConverter - Converting 'Integer' value '0' to type 'Long'
11:28:31.613 [main] DEBUG org.apache.commons.beanutils.converters.LongConverter -     Converted to Long value '0'
11:28:31.613 [main] DEBUG org.apache.commons.beanutils.converters.ShortConverter - Setting default value: 0
11:28:31.613 [main] DEBUG org.apache.commons.beanutils.converters.ShortConverter - Converting 'Integer' value '0' to type 'Short'
11:28:31.613 [main] DEBUG org.apache.commons.beanutils.converters.ShortConverter -     Converted to Short value '0'
11:28:31.615 [main] DEBUG org.apache.commons.beanutils.converters.BigDecimalConverter - Setting default value: 0.0
11:28:31.615 [main] DEBUG org.apache.commons.beanutils.converters.BigDecimalConverter - Converting 'BigDecimal' value '0.0' to type 'BigDecimal'
11:28:31.615 [main] DEBUG org.apache.commons.beanutils.converters.BigDecimalConverter -     No conversion required, value is already a BigDecimal
11:28:31.615 [main] DEBUG org.apache.commons.beanutils.converters.BigIntegerConverter - Setting default value: 0
11:28:31.615 [main] DEBUG org.apache.commons.beanutils.converters.BigIntegerConverter - Converting 'BigInteger' value '0' to type 'BigInteger'
11:28:31.615 [main] DEBUG org.apache.commons.beanutils.converters.BigIntegerConverter -     No conversion required, value is already a BigInteger
11:28:31.615 [main] DEBUG org.apache.commons.beanutils.converters.BooleanConverter - Setting default value: false
11:28:31.615 [main] DEBUG org.apache.commons.beanutils.converters.BooleanConverter - Converting 'Boolean' value 'false' to type 'Boolean'
11:28:31.615 [main] DEBUG org.apache.commons.beanutils.converters.BooleanConverter -     No conversion required, value is already a Boolean
11:28:31.615 [main] DEBUG org.apache.commons.beanutils.converters.ByteConverter - Setting default value: 0
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.ByteConverter - Converting 'Integer' value '0' to type 'Byte'
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.ByteConverter -     Converted to Byte value '0'
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.CharacterConverter - Setting default value:  
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.CharacterConverter - Converting 'Character' value ' ' to type 'Character'
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.CharacterConverter -     No conversion required, value is already a Character
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.DoubleConverter - Setting default value: 0
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.DoubleConverter - Converting 'Integer' value '0' to type 'Double'
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.DoubleConverter -     Converted to Double value '0.0'
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.FloatConverter - Setting default value: 0
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.FloatConverter - Converting 'Integer' value '0' to type 'Float'
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.FloatConverter -     Converted to Float value '0.0'
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.IntegerConverter - Setting default value: 0
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.IntegerConverter - Converting 'Integer' value '0' to type 'Integer'
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.IntegerConverter -     No conversion required, value is already a Integer
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.LongConverter - Setting default value: 0
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.LongConverter - Converting 'Integer' value '0' to type 'Long'
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.LongConverter -     Converted to Long value '0'
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.ShortConverter - Setting default value: 0
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.ShortConverter - Converting 'Integer' value '0' to type 'Short'
11:28:31.616 [main] DEBUG org.apache.commons.beanutils.converters.ShortConverter -     Converted to Short value '0'
11:28:31.617 [main] DEBUG org.apache.commons.beanutils.converters.StringConverter - Setting default value: 
11:28:31.617 [main] DEBUG org.apache.commons.beanutils.converters.StringConverter - Converting 'String' value '' to type 'String'
11:28:31.622 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Z@180bc46411:28:31.622 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'boolean[]' value '[Z@180bc464' to type 'boolean[]'
11:28:31.622 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a boolean[]
11:28:31.622 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [B@2c6a3f7711:28:31.622 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'byte[]' value '[B@2c6a3f77' to type 'byte[]'
11:28:31.622 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a byte[]
11:28:31.622 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [C@6204384011:28:31.622 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'char[]' value '[C@62043840' to type 'char[]'
11:28:31.622 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a char[]
11:28:31.622 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [D@2ef9b8bc11:28:31.622 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'double[]' value '[D@2ef9b8bc' to type 'double[]'
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a double[]
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [F@1e67b87211:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'float[]' value '[F@1e67b872' to type 'float[]'
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a float[]
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [I@3f2a3a511:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'int[]' value '[I@3f2a3a5' to type 'int[]'
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a int[]
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [J@6fb554cc11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'long[]' value '[J@6fb554cc' to type 'long[]'
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a long[]
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [S@77b52d1211:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'short[]' value '[S@77b52d12' to type 'short[]'
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a short[]
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.math.BigDecimal;@68837a7711:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'BigDecimal[]' value '[Ljava.math.BigDecimal;@68837a77' to type 'BigDecimal[]'
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a BigDecimal[]
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.math.BigInteger;@3567135c11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'BigInteger[]' value '[Ljava.math.BigInteger;@3567135c' to type 'BigInteger[]'
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a BigInteger[]
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.lang.Boolean;@4157f54e11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'Boolean[]' value '[Ljava.lang.Boolean;@4157f54e' to type 'Boolean[]'
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a Boolean[]
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.lang.Byte;@47f647311:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'Byte[]' value '[Ljava.lang.Byte;@47f6473' to type 'Byte[]'
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a Byte[]
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.lang.Character;@6b143ee911:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'Character[]' value '[Ljava.lang.Character;@6b143ee9' to type 'Character[]'
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a Character[]
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.lang.Double;@6615435c11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'Double[]' value '[Ljava.lang.Double;@6615435c' to type 'Double[]'
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a Double[]
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.lang.Float;@3a0346411:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'Float[]' value '[Ljava.lang.Float;@3a03464' to type 'Float[]'
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a Float[]
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.lang.Integer;@617c74e511:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'Integer[]' value '[Ljava.lang.Integer;@617c74e5' to type 'Integer[]'
11:28:31.623 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a Integer[]
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.lang.Long;@67b6d4ae11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'Long[]' value '[Ljava.lang.Long;@67b6d4ae' to type 'Long[]'
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a Long[]
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.lang.Short;@366e2eef11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'Short[]' value '[Ljava.lang.Short;@366e2eef' to type 'Short[]'
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a Short[]
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.lang.String;@3cbbc1e011:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'String[]' value '[Ljava.lang.String;@3cbbc1e0' to type 'String[]'
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a String[]
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.lang.Class;@7225790e11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'Class[]' value '[Ljava.lang.Class;@7225790e' to type 'Class[]'
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a Class[]
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.util.Date;@36f6e87911:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'Date[]' value '[Ljava.util.Date;@36f6e879' to type 'Date[]'
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a Date[]
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.util.Calendar;@3551a9411:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'Calendar[]' value '[Ljava.util.Calendar;@3551a94' to type 'Calendar[]'
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a Calendar[]
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.io.File;@52af6cff11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'java.io.File[]' value '[Ljava.io.File;@52af6cff' to type 'java.io.File[]'
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a java.io.File[]
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.sql.Date;@2c9f9fb011:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'java.sql.Date[]' value '[Ljava.sql.Date;@2c9f9fb0' to type 'java.sql.Date[]'
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a java.sql.Date[]
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.sql.Time;@9f70c5411:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'java.sql.Time[]' value '[Ljava.sql.Time;@9f70c54' to type 'java.sql.Time[]'
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a java.sql.Time[]
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.sql.Timestamp;@737996a011:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'java.sql.Timestamp[]' value '[Ljava.sql.Timestamp;@737996a0' to type 'java.sql.Timestamp[]'
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a java.sql.Timestamp[]
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Setting default value: [Ljava.net.URL;@50f8360d11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter - Converting 'java.net.URL[]' value '[Ljava.net.URL;@50f8360d' to type 'java.net.URL[]'
11:28:31.624 [main] DEBUG org.apache.commons.beanutils.converters.ArrayConverter -     No conversion required, value is already a java.net.URL[]
11:28:31.632 [main] DEBUG org.apache.commons.beanutils.BeanUtils - BeanUtils.copyProperties(Teacher(id=null, name=null), Student(id=125d6364-524b-407c-a426-9d7dfc078305, name=wx, age=22))
11:28:31.645 [main] DEBUG org.apache.commons.beanutils.converters.StringConverter - Converting 'String' value '125d6364-524b-407c-a426-9d7dfc078305' to type 'String'
11:28:31.645 [main] DEBUG org.apache.commons.beanutils.converters.StringConverter - Converting 'String' value 'wx' to type 'String'
Teacher(id=125d6364-524b-407c-a426-9d7dfc078305, name=wx)

接下来使用org.springframework.beans.BeanUtils下的copyProperties方法,执行结果如下:

ini 复制代码
Student(id=e4ce2c33-afe0-47a2-8ef9-209623b73487, name=wx, age=22)
Teacher(id=e4ce2c33-afe0-47a2-8ef9-209623b73487, name=wx)

小结:目标对象中不包含被copy对象的所有字段时,选用springframework的copyProperties方法好一点,而apache的该方法也能出结果,但是内部却做了很多处理,可以看到有许多debug日志信息。在低版本的apache中,还会因为字段值不够而报错。

总结:

1.org.apache.commons.beanutils.BeanUtils和org.springframework.beans.BeanUtils两个包中的copyProperties方法目标对象和源对象参数的位置是相反,使用时需要注意。

2.在使用apache的BeanUtils进行copy对象时,老版本中被copy对象中包含的字段目标对象必须包含,可以有其他的多于字段,类型可以不相同,但字段名称必须一致。在比较新的版本后,整个问题被内部修复。org.springframework.beans.BeanUtils中的没有这个限制。

2.BeanUtils.copyProperties的深浅拷贝问题

2.1深拷贝和浅拷贝

深拷贝和浅拷贝最主要的区别在于是否复制了对象的真实实体还是只是使用了一个指针,两者指向的时内存中的同一个对象。

浅拷贝只是增加了一个指针指向已存在的内存地址;

深拷贝时增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存;同时如果一个类中包含有引用类型变量,则该类拷贝以后引用类型也会被拷贝。

2.2BeanUtils.copyProperties深浅拷贝问题

BeanUtils.copyProperties使用起来虽然方便,但是它其实只是浅拷贝,所以类中都是单一的属性,像咱们上边介绍的,可以直接用;如果类中包含有其他的子类就需要考虑下拷贝后目标对象(target/dest)中包含被copy的对象(source/orig)中的子类是否有可能被修改,如果有可能被修改就不能直接使用。

新增加一个实体类Life,接下来我们将上述中的代码进行一个改造:

typescript 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Life {
    private String life;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private String id;
    private String name;
    private String age;
    private Life life;
}


@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
    private String id;
    private String name;
    private Life life;
}
ini 复制代码
public static void main(String[] args) throws Exception {
    Student student = new Student(UUID.randomUUID().toString(), "wx", "22",new Life("young"));
    Teacher teacher = new Teacher();
    System.out.println(student);
    BeanUtils.copyProperties(student,teacher);
    teacher.getLife().setLife("old");
    System.out.println(student);
}

执行结果如下:
Student(id=2acad1bd-c65b-4563-889f-97c311ed0f15, name=wx, age=22, life=Life(life=young))
Student(id=2acad1bd-c65b-4563-889f-97c311ed0f15, name=wx, age=22, life=Life(life=old))

正常情况下,student中的life值在copy给teacher之后,不管teacher的属性值怎么变化,student应该时不变的,而代码的student中的life确变为了old,说明teacher和student两个对象中的life子对象为内存中的同一个life对象,所以BeanUtils.copyProperties属于浅拷贝。

深拷贝的方法

深拷贝的一种方法是通过序列化实现深拷贝,将集合转化为字节流数组输出流,然后再读取,这样就可以实现深度拷贝,代码如下:

ini 复制代码
public List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {  
		// 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
	    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();  
	    ObjectOutputStream out = new ObjectOutputStream(byteOut);  
	    out.writeObject(src);  
	  
	    ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());  
	    ObjectInputStream in = new ObjectInputStream(byteIn);  
	    @SuppressWarnings("unchecked")  
	    List<T> dest = (List<T>) in.readObject();  
	    return dest;  
	} 
相关推荐
coderWangbuer18 分钟前
基于springboot的高校招生系统(含源码+sql+视频导入教程+文档+PPT)
spring boot·后端·sql
攸攸太上24 分钟前
JMeter学习
java·后端·学习·jmeter·微服务
Kenny.志27 分钟前
2、Spring Boot 3.x 集成 Feign
java·spring boot·后端
sky丶Mamba44 分钟前
Spring Boot中获取application.yml中属性的几种方式
java·spring boot·后端
千里码aicood2 小时前
【2025】springboot教学评价管理系统(源码+文档+调试+答疑)
java·spring boot·后端·教学管理系统
程序员-珍2 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
liuxin334455662 小时前
教育技术革新:SpringBoot在线教育系统开发
数据库·spring boot·后端
数字扫地僧3 小时前
HBase与Hive、Spark的集成应用案例
后端
架构师吕师傅3 小时前
性能优化实战(三):缓存为王-面向缓存的设计
后端·微服务·架构
bug菌3 小时前
Java GUI编程进阶:多线程与并发处理的实战指南
java·后端·java ee