Как получить метод, используя отражение java только с частичным именем в виде строки метода?

Я пытаюсь вызвать геттер класса, у меня есть только частичное имя, такое как «Имя», «возраст» и т. д. Мне нужно динамически вызывать метод из класса, такого как getName/retriveName, на основе геттеров, использующих java Reflection API.

например:

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;
}
}

Я могу получить «имя»/«Имя» на основе пользовательского ввода, я должен вызывать только метод getName(). Пожалуйста, помогите.


person Karthikeyan    schedule 20.02.2017    source источник
comment
Преобразуйте ввод в нижний регистр, затем сделайте первую букву заглавной, а затем добавьте полученную строку к "getPerson", чтобы получить полное имя метода?   -  person Arnaud    schedule 20.02.2017


Ответы (3)


В java 8 вы можете сделать так:

  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();
  }

Выводы: «Найден метод с именем: getPersonName, который вернул: Janek»

person walkeros    schedule 20.02.2017
comment
Вы можете использовать Arrays.stream(PersonData.class.getDeclaredMethods()) вместо объезда asList(…).stream(). - person Holger; 21.02.2017

Ммм, на самом деле это не очень хорошая идея, вам нужно либо использовать методы GETALL и искать по имени (например, регулярное выражение), либо указать полное имя отверстия, которое вы хотите вызвать....

    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;
        }
    }

теперь подумайте, что может произойти, если в вашем классе есть какой-то метод, например

public String getContentNamespace() {
    return aNamespace;
}

и пользователь вводит имя в качестве ввода....

тогда, возможно, вы вызовете неправильный метод....

person ΦXocę 웃 Пepeúpa ツ    schedule 20.02.2017

Наличие полей personName, personAge и personId внутри класса с именем PersonData обычно (но не всегда) является плохой практикой, это очень избыточно, и у этого антипаттерна даже есть имя: smurf naming.

Но, к счастью, вопрос самостоятельный. Чтобы получить значение свойства на основе частичного совпадения, вам нужно будет перечислить все методы получения свойств и выбрать тот, имя которого содержит предоставленную строку.

person Tamas Hegedus    schedule 20.02.2017