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?
source to share
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
source to share
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);
source to share
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);
}
}
}
source to share