3

I am trying to invoke a getter of a class, I have only the partial name such as "Name", "age" etc. I need to invoke the method from class like getName/retriveName dynamically based on the getters using java Reflection api.

for eg:

class PersonData{

private String personName;
private int personId;
private int personAge;

public PersonData(){
}

public int getPersonId(){
    return this.personID;
}

public String getPersonName(){
    return this.personName;
}

public int getPersonAge(){
    return this.PersonAge;
}
}

I may get "name"/"Name" based on the user input, I should invoke the method getName() only. Kindly help.

Karthikeyan
  • 439
  • 1
  • 4
  • 8
  • 1
    Transform the input to lower case, then capitalize the first letter, then append the resulting String to `"getPerson"` to get the full method name ? – Arnaud Feb 20 '17 at 09:13

3 Answers3

2

In java 8 you can do like this:

  public static void main(String[] args) throws Exception {
    final PersonData person = new PersonData("Janek", 111, 59);

    final Method method = getMethodLike("naMe");

    final Object output = method.invoke(person);

    System.out.println("Found method with name: " + method.getName() + " which returned: " + output);


  }

  private static Method getMethodLike(String partOfName) {
    final Optional<Method> matchedMethod = asList(PersonData.class.getDeclaredMethods()).stream().filter(method ->
      method.getName().toLowerCase().indexOf(partOfName.toLowerCase()) >= 0).findAny();

    if (!matchedMethod.isPresent()) {
      throw new RuntimeException("No method containing: " + partOfName);
    }

    return matchedMethod.get();
  }

Outputs: "Found method with name: getPersonName which returned: Janek"

walkeros
  • 3,745
  • 4
  • 26
  • 38
  • You can use `Arrays.stream(PersonData.class.getDeclaredMethods())` instead of the `asList(…).stream()` detour. – Holger Feb 21 '17 at 19:14
0

Ummm,n ot really a goot idea, you have to either GETALL methods and search by name (regex for example) or provide the hole full name of the mothod you want to invoke....

    PersonData i = new PersonData();
    String userInp = "name";
    Class<PersonData> ri = (Class<PersonData>) Class.forName(PersonData.class.getName());
    Method[] m = ri.getDeclaredMethods();
    for (Method method : m) {
        System.out.println(method);
        if (method.getName().toLowerCase().indexOf(userInp.toLowerCase()) != -1) {
            System.out.println("....method found! -> " + method);
            break;
        }
    }

now consider what could happen if your class has some method like

public String getContentNamespace() {
    return aNamespace;
}

and the user gives name as input....

then maybe you will invoke the wrong method....

ΦXocę 웃 Пepeúpa ツ
  • 43,054
  • 16
  • 58
  • 83
0

Having personName, personAge and personId fields inside a class named PersonData is usually (but not always) bad practice, it's highly redundant and this antipattern even has a name: smurf naming.

But fortunately the question is independent. To get a property value based on partial match you will have to list all property getters and select the one whose name contains the provided string.

Tamas Hegedus
  • 24,663
  • 9
  • 48
  • 87