JAVA。对深层复制对象使用反射

问题描述 投票:1回答:1

我尝试通过反射复制对象。我对复制原始类型没有困难,但是我不理解复制引用类型。

import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
public class ReflMethod {
    private static final Set<Class<?>> WRAPPER_TYPES = getWrapperTypes();

    public Object CopyObject(Object object) throws ClassNotFoundException, IllegalAccessException, InstantiationException {

        Class clazz = object.getClass();
        Field[] fields = clazz.getDeclaredFields();
        Object instance =  object.getClass().newInstance();

        for(Field field : fields) {
            field.setAccessible(true);
            Class newClass = Class.forName(field.get(object).getClass().getName());
            if(isWrapperType(newClass)) {
                field.set(instance, field.get(object));
            }
            else if(!isWrapperType(newClass)) {

                //WEIRDNESS HERE
                field.set(instance, CopyObject(field.get(object).getClass().getName()));
                //WEIRDNESS HERE
            }
        }
        return instance;
    }

    public static boolean isWrapperType(Class<?> clazz)
    {
        return WRAPPER_TYPES.contains(clazz);
    }

    public static Set<Class<?>> getWrapperTypes()
    {
        Set<Class<?>> ret = new HashSet<Class<?>>();
        ret.add(Boolean.class);
        ret.add(Character.class);
        ret.add(Byte.class);
        ret.add(Short.class);
        ret.add(Integer.class);
        ret.add(Long.class);
        ret.add(Float.class);
        ret.add(Double.class);
        ret.add(Void.class);
        return ret;
    }
}

我想使用递归来复制引用类型...我认为哪里错了?

public class Cat {
    private Phone phone;
    private int age;

    public Cat() {

    }

    public Cat(int age, Phone phone) {
        this.age = age;
        this.phone = phone;
    }

    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Phone getPhone() {
        return phone;
    }
    public void setPhone(Phone phone) {
        this.phone = phone;
    }
}
public class Phone {
    private String name;
    public Phone() {

    }
    public Phone(String name) {
        this.name = name;
    }
    public void SetName(String name) {
        this.name = name;
    }
    public String GetName() {
        return name;
    }
}

和主要班级:

public class MainClass {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException {

        ReflMethod reflMethod = new ReflMethod();

        Phone phone1 = new Phone("IPhone");
        Cat cat1 = new Cat(20, phone1);
        Cat cat2 = (Cat)reflMethod.CopyObject(cat1);

        System.out.println("cat1 : " + cat1.getAge() + " " + cat1.getPhone().GetName());
        System.out.println("cat2 : " + cat2.getAge() + " " + cat2.getPhone().GetName());
        cat1.setAge(100);
        Phone phone = new Phone("Af");
        cat1.setPhone(phone);
        System.out.println("cat1 : " + cat1.getAge() + " " + cat1.getPhone().GetName());
        System.out.println("cat2 : " + cat2.getAge() + " " + cat2.getPhone().GetName());
    }
}

由于该代码被标记为WEIRDNESS HERE,因此该代码无法使用。

java reflection deep-copy
1个回答
0
投票

答案是在Stackoverflow的深处找到的:D

但是它不适用于集合:(

ReflMethod:

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class ReflMethod {


    public static Object CopyObject(Object object)
    {
        try
        {
            Object clone = object.getClass().newInstance();

            for(Field field : object.getClass().getDeclaredFields()) {
                field.setAccessible(true);

                if(field.get(object) == null || Modifier.isFinal(field.getModifiers()))
                {
                    continue;
                }

                if(field.getType().isPrimitive()
                        || field.getType().equals(String.class)
                        || field.getType().getSuperclass().equals(Number.class)
                        || field.getType().equals(Boolean.class))
                {
                    field.set(clone, field.get(object));
                }
                else {
                    Object childObj = field.get(object);
                    if(childObj == object) {
                        field.set(clone,clone);
                    }
                    else {
                        field.set(clone,CopyObject(field.get(object)));
                    }
                }
            }
            return clone;
        }
        catch (Exception e) {
            return  null;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.