直接上代码:自定义注解、对象准备(源对象、目标对象)
自定义注解
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
@Target({FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CopyAnnotation {
String value();
Class type();
}
一、源对象
public class Resource {
@CopyAnnotation(value = "name",type = Target.class)
private String names;
@CopyAnnotation(value = "age",type = Target.class)
private int ages;
@CopyAnnotation(value = "object", type = Target.class)
private Object objects;
public Resource(String names,int ages,Object objects){
this.names = names;
this.ages = ages;
this.objects = objects;
}
public Resource(int ages,Object objects){
this.ages = ages;
this.objects = objects;
}
public Resource(){
}
public String getNames() {
return names;
}
public void setNames(String names) {
this.names = names;
}
public int getAges() {
return ages;
}
public void setAges(int ages) {
this.ages = ages;
}
public Object getObjects() {
return objects;
}
public void setObjects(Object objects) {
this.objects = objects;
}
}
二、目标对象
public class Target {
private int age;
private String name;
private Object object;
public Target(String name,int age){
this.name = name;
this.age = age;
}
public Target(){
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
}
三、属性复制工具类
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 对象属性复制类
* 将源对象中的属性值复制到目标对象中去
* 如果源对象和目标对象相同的业务字段,属性名不相同。可以采用在源对象属性上加注解的方式,构建映射关系
*/
public class CopyUtil {
private static Class myAnnotation = CopyAnnotation.class;
/**
* 对象属性赋值方法
* 将 V 中的属性值,按照属性名的对应关系,复制到 K 中去
* @param k K 目标类
* @param v V 源对象
* @param <K> 泛型
* @param <V> 泛型
*/
public static <K, V> void copy(K k, V v) {
// 1.通过反射获取到b的属性值列表
Field[] fields = v.getClass().getDeclaredFields();
try {
for (Field field : fields) {
// 1.获取属性名到源对象中的属性值(getter方式)
Object value = getFieldValueByName(field.getName(), v);
// 2.如果属性值为null,跳过该属性复制
if (value == null) {
continue;
}
// 3.获取属性CopyAnnotation注解(自定义)的value值(对应的是目标对象的属性名)
// 没有自定义注解,或者自定义注解没有对value属性赋值:使用原有的属性名
String annotationName = getMyAnnotationValue(field);
// 4.使用setter的方式将值复制到目标对象
setTargetFieldValueByNameAndValue(k, annotationName, field.getType(), value);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println("====================对象属性赋值完成====================");
}
/**
* 根据属性名,对象获取对象的属性值
*
* @param name 属性名
* @param v 对象
* @param <V> 泛型方法
* @return Object 属性值
* @throws IllegalAccessException IllegalAccessException
* @throws NoSuchMethodException NoSuchMethodException
* @throws InvocationTargetException InvocationTargetException
*/
private static <V> Object getFieldValueByName(String name, V v)
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
String firstLetter = name.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + name.substring(1);
Method method = v.getClass().getMethod(getter, new Class[]{});
return method.invoke(v, new Class[]{});
}
/**
* 根据对象、属性名、参数类型、参数值
* 使用反射调用setter进行对象属性的赋值操作
*
* @param k 对象
* @param name 属性名
* @param parameterClass 参数类型
* @param value 参数值
* @param <K> 泛型
* @throws NoSuchMethodException NoSuchMethodException
* @throws InvocationTargetException InvocationTargetException
* @throws IllegalAccessException IllegalAccessException
*/
private static <K> void setTargetFieldValueByNameAndValue(K k, String fieldName, Class parameterClass, Object value)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String setter = "set" + firstLetter + fieldName.substring(1);
Method method;
method = k.getClass().getMethod(setter, new Class[]{parameterClass});
method.invoke(k, value);
}
/**
* 获取属性上自定义注解的value值
*
* @param field Field
* @return String
*/
private static String getMyAnnotationValue(Field field) {
CopyAnnotation annotation = (CopyAnnotation) field.getAnnotation(myAnnotation);
if (annotation == null || annotation.value() == null) {
return field.getName();
}
return annotation.value();
}
}
四、测试类
/**
* @ClassName Test
* @Deacription TODO
* @Author gongyunlong
* @Date 2019/11/4 16:40
* @Version 1.0
**/
public class Test {
public static void main(String[] args) {
Resource resource = new Resource("要复制的属性",1,new Object());
// Resource resource = new Resource(1,new Object());
Target target = new Target();
CopyUtil.copy(target,resource);
}
}
五、尚未解决的问题
尚未解决复杂对象间的属性复制操作