直接上代碼:自定義註解、對象準備(源對象、目標對象)
自定義註解
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);
}
}
五、尚未解決的問題
尚未解決複雜對象間的屬性複製操作