Reflection IllegalArgumentException

I need to get private fields from one class and set them to another class.

This code works fine for Integer test fields (100500 value is written):

//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));       
}

      

However, when I switch to undefined (the fields are DIFFERENT types: Dates, Integers, Strings ...

For example, class one has Date and the second class is Date, I need to copy one value from the other, but the next field will be a String in both classes)

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

      

I am getting IllegalArgumentException for example. I cannot get values ​​from one class and set it to another.

Please, dear community, give me a hint - what am I doing wrong?

+3


source to share


3 answers


to me it looks like you are passing a field reference instead of a field value:

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        
        }

      



although I wouldn't do that, because order is fragile ... you can use beanutils to copy the beans if so, which is what you want to achieve

+2


source


This should suit your needs:

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);
    }
}

      



To call:

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

      

+2


source


Your error seems to be related to the fact that you are trying to set Field1 as a field parameter instead of Field1's value.

field.set(app,  field1);  

      

it should be

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

      

Check out a small working example ;

If you change

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

      

to

fieldDest.set(destination, fieldSrc);

      

you will get the same error from this question.

Hope it helps.

Example code:

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);
        }
    }    
}

      

+1


source







All Articles