отражение получить и установить строку

#java #jakarta-ee #reflection

#java #джакарта-ee #отражение

Вопрос:

Я хочу обрезать любые строковые поля класса, используя отражение, но я сталкиваюсь с этим исключением, когда я запускал программу :

 Exception in thread "main" java.lang.NoSuchMethodException: BeanX.setName()
at java.lang.Class.getMethod(Class.java:1624)
at Test.trimStr(Test.java:19)
at Test.main(Test.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
  

вот мой BeanX контейнер данных POJO:

 public class BeanX {

    private String name;

    private String fname;

    private long age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    public long getAge() {
        return age;
    }

    public void setAge(long age) {
        this.age = age;
    }
}
  

и вот мой тестовый класс и мой необычный метод, но я не знаю, почему возникает это исключение:

 import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test {
    public  <T> T trimStr(T t) throws Exception{
        Class clazz = t.getClass();
        Field[] fields = clazz.getDeclaredFields();
        Method unknownMethod;
        for(int i=0; i<fields.length; i  ){
            if(fields[i].getType().isAssignableFrom(String.class)){
                String fieldName = fields[i].getName().substring(0, 1).toUpperCase()   fields[i].getName().substring(1);
                unknownMethod = clazz.getMethod("get" fieldName);
                String strValue = unknownMethod.invoke(t).toString();

                unknownMethod = clazz.getMethod("set" fieldName);
                String newValue = strValue.trim();
                unknownMethod.invoke(t, new String(strValue.trim()));
            }
        }
     return t;
    }


    public static void main(String ... args)throws Exception{
        BeanX x = new BeanX();

        x.setAge(2L);
        x.setName("John   ");
        x.setFname("   X");
        System.out.println(x.getName() ";");
        Test tee = new Test();
        BeanX y = tee.trimStr(x);
        System.out.println(y.getName() ";");    
    }
}
  

Комментарии:

1. Вы читали javadoc getMethod ? Какие аргументы оно принимает?

2. проблема в том, что setMethod не GetMethod

3. Ваша трассировка стека показывает обратное at java.lang.Class.getMethod(Class.java:1624)

4. Нет setMethod . Я не имею в виду геттеры и сеттеры.

5. При работе с Beans рассмотрите возможность использования java.beans. Интроспектор и получает метод чтения / записи из PropertyDescriptor.

Ответ №1:

Ваша проблема здесь:

 clazz.getMethod("set" fieldName);
  

Из JavaDoc для Class :

открытый метод GetMethod(имя строки, класс … типы параметров) вызывает исключение noSuchMethod, исключение SecurityException

Возвращает объект метода, который отражает указанный открытый метод-член класса или интерфейса, представленный этим объектом класса. Параметр name представляет собой строку, указывающую простое имя нужного метода. Параметр parameterTypes представляет собой массив объектов класса, которые идентифицируют формальные типы параметров метода в объявленном порядке. Если parameterTypes имеет значение null, он обрабатывается так, как если бы это был пустой массив.

Вы не передали никаких аргументов, поэтому он ищет метод, который не принимает аргументов.

Предположительно, ваш setter будет принимать String аргумент:

 clazz.getMethod("set" fieldName, String.class);
  

Комментарии:

1. спасибо, моя ошибка — мои глаза действительно не видели эту маленькую смешную часть после 18 часов кодирования .. спасибо, приятель

2. @JohnX всего через 18 часов? Разве это не стандартный сдвиг в мире программирования?

3. Я думаю, что стандарт составляет 8 часов, поэтому накладные расходы составляют 10 часов… Я пытаюсь воскресить мертвый проект, и я работаю внештатно и дома. сколько часов вы, ребята, работаете над кодом в день?