反射IllegalArgumentException

时间:2013-02-04 10:49:28

标签: java reflection

我需要从一个类中获取私有字段并将它们设置为另一个类。

此代码非常适用于测试整数字段(写入100500值):

//get objects, class firs...

for(int i =0; i<fields1.length; i++) {
    Field field1 = fields1 [i];
    Field field = fields [i];
    field.setAccessible(true);
    field.set(app,  new Integer(100500));       
}

但是,当我切换到未定义的类型时(字段是不同类型的:日期,整数,字符串......

例如,第一类有Date,第二类有Date,我需要从另一个复制一个值,但是下一个字段在两个类中都是String)

for(int i =0; i<fields1.length; i++) {
    Field field1 = fields1 [i];
    Field field = fields [i];
    field.setAccessible(true);
    field.set(app,  field1);        
}

我收到IllegalArgumentException,例如我实际上无法从一个类中获取值并将其设置为另一个类。

亲爱的社区,请给我一个提示 - 我做错了什么?

3 个答案:

答案 0 :(得分:2)

对我来说,看起来你交出了字段引用而不是字段值:

for(int i =0; i<fields1.length; i++) {
        Field field1 = fields1 [i];
        Field field = fields [i];
        field.setAccessible(true);
        field.set(app,  field1.get(app1)); //or whatever object field1 is from        
        }

虽然我不这样做,因为订单是一件脆弱的事情...... 您可以使用beanutils复制您的bean,如果是,您想要实现的目标

答案 1 :(得分:2)

这应该符合您的需求:

public static <T> void copyDeclaredFields(T from, T to) throws Exception {
    Class<?> clazz = from.getClass();
    if (!clazz.equals(to.getClass())) {
        throw new IllegalArgumentException();
    }
    for (Field field : clazz.getDeclaredFields()) {
        Object value = field.get(from);
        field.set(to, value);
    }
}

致电:

Item item1 = new Item();
// item1.set...
Item item2 = new Item();
copyDeclaredFields(item1, item2);

答案 2 :(得分:1)

您的错误似乎与您尝试将 Field1 设置为Field的参数而不是Field1的这一事实有关。

field.set(app,  field1);  

应该是

field.set(app,  field1.get(app1));

看看a small working example;

如果你改变了

fieldDest.set(destination, fieldSrc.get(source));

fieldDest.set(destination, fieldSrc);

你会得到同样的错误。

希望有所帮助。

示例代码:

import java.util.*;
import java.lang.*;
import java.lang.reflect.*;

class Main
{

        public static void main (String[] args) throws java.lang.Exception
        {
            Source source = new Source();
        Destination destination = new Destination();


        Class sourceClassObject = source.getClass();
        Class destClassObject = destination.getClass();
        Field[] sourceFields = sourceClassObject.getDeclaredFields();
        Field[] destFields = destClassObject.getDeclaredFields();

        for (Field fieldSrc : sourceFields) {
            int mod = fieldSrc.getModifiers();  // get modifiers
            System.out.print("Source Field: " + Modifier.toString(mod) + " "
              + fieldSrc.getType() + " " + fieldSrc.getName());
            fieldSrc.setAccessible(true);
            System.out.println(" [" + fieldSrc.get(source) + "]");
            for (Field fieldDest : destFields){
                if (fieldDest.getType().equals(fieldSrc.getType()) && 
                    fieldDest.getName().equals(fieldSrc.getName())){
                    fieldDest.setAccessible(true);
                    fieldDest.set(destination, fieldSrc.get(source));
                }                
            }
        }

        destination.printValues();
    }

    static class Source{        

        public Source(){
            strField = "This is a String";
            intField = 42;
            dateField = new Date();
        }

        private String  strField;
        private Integer intField;
        private Date    dateField;
    }

    static class Destination{        
        private String  strField;
        private Integer intField;
        private Date    dateField;

        public void printValues(){
            System.out.println("Destination Field values: ");
            System.out.println("strField: " + strField);
            System.out.println("intField: " + intField);
            System.out.println("dateField: " + dateField);
        }
    }    
}