While using java reflection, Can we set a private field without having to tell the parameter type.
For example, if this is my Child
class,
package reflection;
public class Child {
private String name;
private Integer value;
private boolean flag;
public String getLName()
{
return this.name;
}
public void setName(String name)
{
this.name = name;
}
public Integer getValue()
{
return this.value;
}
public void setValue(Integer value)
{
this.value = value;
}
public boolean getFlag()
{
return this.flag;
}
public void setFlag(boolean flag)
{
this.flag = flag;
}
public String toString()
{
return "Name" + this.name;
}
}
I want to set fields of this Child
class in my Tester
class.
package reflection;
public class Tester {
public static void main(String args[]) throws Exception
{
Class<?> clazz = Class.forName("reflection.Child");
Object cc = clazz.newInstance();
cc.getClass().getMethod("setName", String.class).invoke(cc,"AAA");
}
}
Here I am setting the value of Name
field.
In the line,
cc.getClass().getMethod("setName", String.class).invoke(cc,"AAA");
I have used String.class
. Is there a way to do this, without having to tell the field type. Can Java automatically identify the type somehow?
This is because I will get the name, value and flag data from a csv
file, and I want to set all the three fields in a single line using a loop.
I will declare an array of String with values - "setName", "setValue" and "setFlag" and then I want to use something of the following
cc.getClass().getMethod(array[index]).invoke(cc,data);
I know the above statement is wrong, but is there some alternative to this?
2 Answers 2
Get all the methods and find the matching one, which has type info about the parameters:
String name;
String value;
Method[] methods = Child.class.getMethods();
for (Method method : methods) {
if (!method.getName().equals(name))
continue;
Class<?> paramType = method.getParameterTypes()[0];
//You will have to figure how to convert the String value to the parameter.
method.invoke(child, paramType.cast(value)); // for example
}
-
Is there a way not to loop through all methods?Grzegorz Górkiewicz– Grzegorz Górkiewicz2017年03月05日 14:59:32 +00:00Commented Mar 5, 2017 at 14:59
-
@GrzegorzGórkiewicz not unless you know the parameter type, which you said you don't know. If you know the parameter type, you can call
Child.class.getMethod(name, parameterClass)
to get the exact method.2017年03月05日 15:02:38 +00:00Commented Mar 5, 2017 at 15:02 -
But the parameter type is always...
value.getClass()
... i.e.data.getClass()
as in my answer or?Grzegorz Górkiewicz– Grzegorz Górkiewicz2017年03月05日 15:03:48 +00:00Commented Mar 5, 2017 at 15:03 -
But you said your values are from a CSV, which are all Strings2017年03月05日 15:04:51 +00:00Commented Mar 5, 2017 at 15:04
-
Yep. The OP (not me) would have to use some redundant ifs or switches to infer type, when following my answer.Grzegorz Górkiewicz– Grzegorz Górkiewicz2017年03月05日 15:05:58 +00:00Commented Mar 5, 2017 at 15:05
You could use Apache Commons FieldUtils.writeDeclaredField
Child childObject = new Child();
FieldUtils.writeDeclaredField(childObject, "name", "John", true);
n -> c.setName(n)
, instead of an array of strings?