Tabla de contenido
1. Antecedentes del problema
Al 源对象
copiar 目标对象
, los atributos heredados de la clase principal en el objeto de destino no se copiaron correctamente.
2. Método BeanUtils.copyProperties de Spring
BeanUtils.copyProperties
Cuando se utiliza el método de Spring para copiar atributos, solo se copiarán los atributos definidos en el objeto de origen, pero no se copiarán los atributos heredados de la clase principal en el objeto de destino . Debido a que BeanUtils.copyProperties()
el método se implementa en función de la reflexión de Java, solo puede acceder a las propiedades en el objeto de origen y no puede acceder a las propiedades heredadas de la clase principal en el objeto de destino.
Si necesita copiar atributos del objeto de origen al objeto de destino, incluidos los atributos heredados de la clase principal en el objeto de destino, puede utilizar otras herramientas de mapeo de objetos Java, como BeanUtil de Hutool, Apache Commons BeanUtils y Dozer. Estas herramientas se pueden configurar para decidir si se copian las propiedades heredadas de la clase principal.
3. demostración
BeanUtil.copyProperties()
El siguiente es un código de muestra para copiar atributos usando el método en Hutool :
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import java.util.*;
public class Example {
public static void main(String[] args) {
// 创建一个子类对象
Child source = new Child();
source.setPublicField("public field");
source.setProtectedField("protected field");
source.setPrivateField("private field");
source.setDateField(DateUtil.parse("2023-05-22"));
source.setStringList(CollUtil.newArrayList("a", "b", "c"));
source.setStringMap(new HashMap<String, String>() {
{
put("key1", "value1");
put("key2", "value2");
}});
// 创建一个父类对象
Parent target = new Parent();
// 将子类对象的属性拷贝到父类对象中
BeanUtil.copyProperties(source, target);
// 输出父类对象中的属性
System.out.println("publicField: " + target.getPublicField());
System.out.println("protectedField: " + target.getProtectedField());
System.println("privateField: " + target.getPrivateField());
System.out.println("dateField: " + target.getDateField());
System.out.println("stringList: " + target.getStringList());
System.out.println("stringMap: " + target.getStringMap());
}
}
// 父类
class Parent {
private String privateField;
private Date dateField;
private List<String> stringList;
private Map<String, String> stringMap;
public String getPrivateField() {
return privateField;
}
public void setPrivateField(String privateField) {
this.privateField = privateField;
}
public Date getDateField() {
return dateField;
}
public void setDateField(Date dateField) {
this.dateField = dateField;
}
public List<String> getStringList() {
return stringList;
}
public void setStringList(List<String> stringList) {
this.stringList = stringList;
}
public Map<String, String> getStringMap() {
return stringMap;
}
public void setStringMap(Map<String, String> stringMap) {
this.stringMap = stringMap;
}
}
// 子类
class Child extends Parent {
public String publicField;
protected String protectedField;
public String getPublicField() {
return publicField;
}
public void setPublicField(String publicField) {
this.publicfield = publicField;
}
public String getProtectedField() {
return protectedField;
}
public void setProtectedField(String protectedField) {
this.protectedField = protectedField;
}
private String privateField;
public String getPrivateField() {
return privateField;
}
public void setPrivateField(String privateField) {
this.privateField = privateField;
}
}
La salida es:
publicField: public field
protectedField: protected field
privateField: private field
dateField: Mon May 22 00:00:00 CST 2023
stringList: [a, b, c]
stringMap: {key1=value1, key2=value2}
4. Suplemento (la diferencia entre BeanUtils.copyProperties de Spring y BeanUtil.copyProperties de hutool)
Tanto Spring BeanUtils.copyProperties()
como Hutool BeanUtil.copyProperties()
son métodos de herramienta para copiar propiedades de objetos, pero tienen algunas diferencias en los detalles de implementación y el uso:
1. La implementación subyacente es diferente.
El método de Spring BeanUtils.copyProperties()
se implementa en base a la reflexión de Java, que puede copiar propiedades en el objeto de origen al objeto de destino y admite conversión de tipos y convertidores personalizados.
El método en Hutool BeanUtil.copyProperties()
se implementa en base a operaciones de código de bytes ASM y no solo puede copiar los atributos del objeto de origen al objeto de destino, sino que también admite reglas de mapeo personalizadas, filtrado de campos y conversión de tipos.
2. Diferentes métodos de uso
El método de Spring BeanUtils.copyProperties()
se utiliza de la siguiente manera:
BeanUtils.copyProperties(source, target);
Entre ellos, source
está el objeto de origen y target
el objeto de destino.
BeanUtil.copyProperties()
El método en Hutool se utiliza de la siguiente manera:
BeanUtil.copyProperties(source, target, ignoreNullValue);
Entre ellos, source
se encuentra el objeto de origen, target
el objeto de destino y ignoreNullValue
un valor booleano que indica si se ignoran los atributos nulos en el objeto de origen. Si ignoreNullValue
es verdadero, las propiedades con valores nulos en el objeto de origen se ignorarán y no se copiarán en el objeto de destino; si es ignoreNullValue
falso, las propiedades con valores nulos en el objeto de origen se copiarán en el objeto de destino .
3. Diferentes tipos compatibles
Los métodos de Spring BeanUtils.copyProperties()
admiten una amplia gama de tipos, incluidos tipos básicos de Java, cadenas, fechas, colecciones, matrices, etc.
Los métodos en Hutool BeanUtil.copyProperties()
también admiten una amplia gama de tipos, incluidos tipos básicos de Java, cadenas, fechas, colecciones, matrices, etc., pero también admiten algunos otros tipos, como enumeraciones, mapas, JSONObject, etc.