Issue
I have a class as follows:
public class MyClass {
@JsonProperty("my_id")
private String id;
public getId() {
return this.id;
}
public setId(String id) {
this.id = id;
}
}
I have another class where I have the JsonProperty [my_id] information with me. With this information, I would like to trigger the getId() and setId() methods.
public class AnotherClass {
// jsonProperty value is "my_id"
public myMethod(MyClass myClass, String jsonProperty, String newId) {
// call the setter method setId(newId) of myClass
// call the getter method getId() of myClass
}
}
I do understand that this is a classic case of Reflection in Java but I am unable to implement the same even after going through hours of documentation and resources on reflection. Can someone please help me here?
Would it also be possible to use Jackson ObjectMapper or Google Gson to get the desired result?
Edit:
Two of the solutions provided by "@gmrm" and "@suraj tomar" does the intended task [Thank you both]. But, both solutions are forced to iterate over each of the available fields. Instead of iterating over all the "Fields", isn't there a way to simply fetch the Field I am looking for based on the JsonProperty name? As an example:
public void myMethod(MyClass myClass, String jsonProperty, String newId) throws IllegalAccessException {
for (Field field : MyClass.class.getDeclaredFields()) {
JsonProperty jsonPropAnnotation = field.getAnnotation(JsonProperty.class);
if (jsonPropAnnotation != null)
if (jsonPropAnnotation.value().equals(jsonProperty)) {
field.setAccessible(true);
field.set(myClass, newId);
}
}
}
The solution above works. Yet, I would like to avoid the loop below, if at all it is possible.
for (Field field : MyClass.class.getDeclaredFields())
Solution
If you don't have message with you, in that case I think reflection only can help you and if you use reflection you even don't need to call setter method for setting value, you can use below code to set the value-
public void myMethod(MyClass myClass, String jsonProperty, String newId) throws IllegalAccessException {
for (Field field : MyClass.class.getDeclaredFields()) {
JsonProperty jsonPropAnnotation = field.getAnnotation(JsonProperty.class);
if (jsonPropAnnotation != null)
if (jsonPropAnnotation.value().equals(jsonProperty)) {
field.setAccessible(true);
field.set(myClass, newId);
}
}
}
Without iterating with for loop you cant set value but you can change approach where at application start up you can populate a static map like below and then in your application you can just get field from map and can set the value without iterating again over loop.
public class MainClass {
private static final Map<String, Field> FIELD_MAP = new HashMap<>();
public static void main(String[] args) throws IllegalAccessException {
setFieldMap();
MyClass myClass = new MyClass();
myMethod(myClass, "my_id", "1234");
System.out.println(myClass.getId());
}
public static void myMethod(MyClass myClass, String jsonProperty, String newId) throws IllegalAccessException {
Field field = FIELD_MAP.get(jsonProperty);
field.setAccessible(true);
field.set(myClass, newId);
}
public static void setFieldMap() {
for (Field field : MyClass.class.getDeclaredFields()) {
JsonProperty ann = field.getAnnotation(JsonProperty.class);
if (ann != null)
if (null != ann.value()) {
FIELD_MAP.put(ann.value(), field);
}
}
}
}
Answered By - tomar
Answer Checked By - Robin (JavaFixing Admin)