35

I getting class by name and i need to update them with respective data and my question is how to do it with java I want to add the method some dummy data . I don't know the class type I just getting the class name and use reflection to get his data

I use this code to get the class instance and

Class<?> classHandle = Class.forName(className);

Object myObject = classHandle.newInstance();

// iterate through all the methods declared by the class
for (Method method : classHandle.getMethods()) {
    // find all the set methods
    if (method.getName().matches("set[A-Z].*")

And know that I find the list of the set method I want to update it with data how can I do that .

assume that In class name I got person and the class have setSalary and setFirstName etc how can I set them with reflection ?

public class Person {

    public void setSalery(double salery) {
        this.salery = salery;
    }

    public void setFirstName(String FirstName) {
        this.FirstName = FirstName;
    }   
}
tmarwen
  • 15,750
  • 5
  • 43
  • 62
Stefan Strooves
  • 624
  • 2
  • 10
  • 16

4 Answers4

87

Instead of trying to call a setter, you could also just directly set the value to the property using reflection. For example:

public static boolean set(Object object, String fieldName, Object fieldValue) {
    Class<?> clazz = object.getClass();
    while (clazz != null) {
        try {
            Field field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(object, fieldValue);
            return true;
        } catch (NoSuchFieldException e) {
            clazz = clazz.getSuperclass();
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }
    return false;
}

Call:

Class<?> clazz = Class.forName(className);
Object instance = clazz.newInstance();
set(instance, "salary", 15);
set(instance, "firstname", "John");

FYI, here is the equivalent generic getter:

@SuppressWarnings("unchecked")
public static <V> V get(Object object, String fieldName) {
    Class<?> clazz = object.getClass();
    while (clazz != null) {
        try {
            Field field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true);
            return (V) field.get(object);
        } catch (NoSuchFieldException e) {
            clazz = clazz.getSuperclass();
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }
    return null;
}

Call:

Class<?> clazz = Class.forName(className);
Object instance = clazz.newInstance();
int salary = get(instance, "salary");
String firstname = get(instance, "firstname");
sp00m
  • 47,968
  • 31
  • 142
  • 252
  • Thanks for your replay ,the issue here is that I don't know the salary and first name since every time I can get different class therefore I can use something like set(myObject, "salery", 15); – Stefan Strooves Jan 17 '13 at 08:56
  • @StefanStrooves So how will you know which field you should set on which class? – sp00m Jan 17 '13 at 08:58
  • one important assumption is that all the classes that I can get have respective set and get for every member, there is no option to the some field will have set without get or vice versa – Stefan Strooves Jan 17 '13 at 09:22
  • what if the modifiers are private? This method surely can't be used to set the properties independently – Akah May 06 '16 at 23:27
  • @larrytech Reflection is more powerful than you think: http://stackoverflow.com/a/3301720/1225328 ;) – sp00m Oct 01 '16 at 12:43
  • why loop on this ?? while (clazz != null) ? – Vikash Mar 27 '18 at 06:32
  • 1
    @Vikash `class` gets overwritten within the `NoSuchFieldException` catch block. This loop basically navigates up through the class hierarchy, so that if the given `fieldName` is not found in the instance class, parent classes will be checked. – sp00m Mar 27 '18 at 08:52
  • Thanks @sp00m. It is really useful. Could you please share a way to set ArrayList and HashMap through reflection? – learner Jul 13 '18 at 10:04
3

To update the first name

  • First find the field you want to update
  • Then find the mutator (which accepts an argument of the field's type)
  • Finally execute the mutator on the object with the new value:
Field field=classHandle.getDeclaredField("firstName");
Method setter=classHandle.getMethod("setFirstName", field.getType());
setter.invoke(myObject, "new value for first name");
paralaks
  • 183
  • 2
  • 7
1
if (method.getName().matches("set[A-Z].*") {
  method.invoke(person,salary)
  // and so on
}

to know the parameters you can issue method.getPagetParameterTypes() based on the result construct your parameters and supply.

tmarwen
  • 15,750
  • 5
  • 43
  • 62
TheWhiteRabbit
  • 15,480
  • 4
  • 33
  • 57
  • The question is (I think) How to determine the arguments to be sent - how to define if the current `method` object expects the `double` or the `String`, and after determining this - how to know what to send to the method. – amit Jan 17 '13 at 08:34
  • Strange assumption, since there is nothing of such kind mentioned in the question. – Kurt Du Bois Jan 17 '13 at 08:48
0
package apple;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Map.Entry;
import java.util.Set;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;

/*
* Employe Details class
 */
class Employee {

   private long id;
   private String name;
   private String userName;
   private Address address;
   private Contact contact;
   private double salary;

   public long getId() {
     return id;
   }
   public void setId(long id) {
      this.id = id;
   }
   public String getName() {
     return name;
   }
   public void setName(String name) {
    this.name = name;
   }
public String getUserName() {
    return userName;
}
public void setUserName(String userName) {
    this.userName = userName;
}
public Address getAddress() {
    return address;
}
public void setAddress(Address address) {
    this.address = address;
}
public Contact getContact() {
    return contact;
}
public void setContact(Contact contact) {
    this.contact = contact;
}
public double getSalary() {
    return salary;
}
public void setSalary(double salary) {
    this.salary = salary;
}
}

/*
 * Address class for employee
*/
class Address {

private String city;
private String state;
private String country;
private int pincode;

public String getCity() {
    return city;
}
public void setCity(String city) {
    this.city = city;
}
public String getState() {
    return state;
}
public void setState(String state) {
    this.state = state;
}
public String getCountry() {
    return country;
}
public void setCountry(String country) {
    this.country = country;
}
public int getPincode() {
    return pincode;
}
public void setPincode(int pincode) {
    this.pincode = pincode;
}

}

/*
 * Contact class for Employee
 */
 class Contact {

private String email;
private String contactNo;

public String getEmail() {
    return email;
}
public void setEmail(String email) {
    this.email = email;
}
public String getContactNo() {
    return contactNo;
}
public void setContactNo(String contactNo) {
    this.contactNo = contactNo;
}

}

public class Server {

public static void main(String args[]) throws JsonSyntaxException, Exception{
    Gson gson = new Gson();

    /*
     * Old Employee Data
     */
    Address address = new Address();
    Contact contact = new Contact();
    Employee employee = new Employee();
    address.setCity("shohna-road");
    address.setCountry("INDIA");
    address.setPincode(12201);
    address.setState("Hariyana");
    contact.setContactNo("+918010327919");
    contact.setEmail("shivritesh9984@gmail.com");
    employee.setAddress(address);
    employee.setContact(contact);
    employee.setId(4389573);
    employee.setName("RITESH SINGH");
    employee.setSalary(43578349.345);
    employee.setUserName("ritesh9984");
    System.out.println("Employee : "+gson.toJson(employee));

    /* New employee data */
    Employee emp = employee;
    address.setCity("OMAX");
    emp.setAddress(address);
    emp.setName("RAVAN"); 

    /* Update employee with new employee Object*/
    update(employee, gson.fromJson(gson.toJson(emp), JsonObject.class) );

    System.out.println("Employee-Update : "+gson.toJson(employee));
}

/*
 * This method update the @target with new given value of new object in json object form
 */
public static  void update(Object target, JsonObject json) throws Exception {
   Gson gson=new Gson();
   Class<? > class1 = target.getClass();

   Set<Entry<String, JsonElement>> entrySet = json.entrySet();
   for (Entry<String, JsonElement> entry : entrySet) {
       String key = entry.getKey();
       Field field = class1.getDeclaredField(key);
       field.setAccessible(true);
       Type genType = field.getGenericType();

       field.set(target,
               gson.fromJson(entry.getValue(),genType));
   }

   }

 }
ritesh9984
  • 418
  • 1
  • 5
  • 17