2

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?

asked Mar 5, 2017 at 14:38
1
  • 1
    Loop through the methods of the class, and find the one called setName. Pray that it isn't overloaded. Note that this has nothing to do with private fields. You're calling public methods here, not setting private fields. That said, like almost all questions related to reflection, reflection is probably not the good way to solve your problem. Why not use an array of Consumer<String>, containing for example n -> c.setName(n), instead of an array of strings? Commented Mar 5, 2017 at 14:52

2 Answers 2

1

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
}
Grzegorz Górkiewicz
4,5964 gold badges24 silver badges39 bronze badges
answered Mar 5, 2017 at 14:53
5
  • Is there a way not to loop through all methods? Commented 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. Commented Mar 5, 2017 at 15:02
  • But the parameter type is always... value.getClass()... i.e. data.getClass() as in my answer or? Commented Mar 5, 2017 at 15:03
  • But you said your values are from a CSV, which are all Strings Commented 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. Commented Mar 5, 2017 at 15:05
1

You could use Apache Commons FieldUtils.writeDeclaredField

Child childObject = new Child();
FieldUtils.writeDeclaredField(childObject, "name", "John", true);
answered Mar 5, 2017 at 16:23

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.