I have created generic json parser using java reflection, but there is a error that i am not able to solve.
Method (at the bottom of this question), receives subclass of my custom Model class. I iterate through fields and set values from json. If subclass contains array property of some other class (which is again, subclass of Model), i've created small recursion to fill those objects.
Eg.
class UserModel extends Model
{
@JsonResponseParam(Name="userName")
public String Name;
@JsonResponseParam(Name="friends")
public FriendModel[] Friends;
}
At the end UserModel should be filled with Friends. (JsonResponseParam is custom anotation, and Name value is used as property for getting values from json)
Result of this method is IllegalArgumentException, and it is thrown on
field.set(t, values.toArray());
Here is the method:
protected <T extends Model> T getModel(T t)
{
Field[] fields = t.getClass().getFields();
for (Field field : fields) {
Annotation an = field.getAnnotation(JsonResponseParam.class);
if(an != null){
try
{
if(field.getType() == boolean.class)
field.setBoolean(t, t.getBool(((JsonResponseParam)an).Name()));
if(field.getType() == String.class)
field.set(t, t.getString(((JsonResponseParam)an).Name()));
if(field.getType() == int.class)
field.setInt(t, t.getInt(((JsonResponseParam)an).Name()));
if(field.getType() == Date.class)
field.set(t, t.getDate(((JsonResponseParam)an).Name()));
if(field.getType().isArray()){
ArrayList<Model> modelArray = t.getModelArray(((JsonResponseParam)an).Name());
ArrayList<Model> values = new ArrayList<Model>();
for (Model model : modelArray) {
Class<? extends Model> arrayType = field.getType().getComponentType().asSubclass(Model.class);
Model m = arrayType.newInstance();
m.jsonObject = model.jsonObject;
model.getModel(m);
values.add(m);
}
field.set(t, values.toArray());
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
return t;
}
I am suspecting on class type inconsistency between field and values..
Thank you for your time.
toArray() only return an Object[]
so it cannot be assigned to any other array type.
What you want is
field.set(t, values.toArray(Array.newInstance(field.getType().getComponentType(), values.size()));
This will create an array of the type to match the field.