【问题标题】:Get the field name from getter method从 getter 方法获取字段名称
【发布时间】:2019-02-01 07:18:48
【问题描述】:

我需要动态捕获 getter 方法的字段名称以进行动态验证和动态格式化。 什么是最好和最有效的方法。

public class Emp{
    private String firstName;
    private String lastName;
    private String address;
    private int age;

    // getter and setters
}


public class MyImplementationClass{

    public execute(Emp emp){
        String fName=emp.getFirstName();
        // field name need to be taken here using 'emp.getFirstName()'
        // need field name and value of return value of 'emp.getFirstName()' for dynamic validation and dynamic formatting.
        // here need to call method validateAndFormat() with field name and value.
    }
}

private String validateAndFormat(String fieldName,String value){
 // read the dynamic validation settings from the xml and  validate/reformat the value
 // this method will validate the field according to xml and return reformatted value.
}
private int validateAndFormat(String fieldName,int value){
//...
}

动态验证设置

<message>
    <element field="firstName" length="22" defaultVal=""></element>
    <element field="lastName" length="20" defaultVal="ibft"></element>
    <element field="address" length="NA" defaultVal=""></element>
    <element field="age" length="NA" defaultVal=""></element>
</message>

【问题讨论】:

  • 请更具体。从您的示例中,我无法理解您真正想要的是什么。如果您调用 getFirstName,那么您想动态找出该方法返回的字段,即使该字段不像方法名称那样被调用?
  • 但是emp.getFirstName() 会返回名字,而不是字段——它甚至可能不会直接由字段支持。该字段是一个实现细节,您不需要关心它。您能否提供有关您要实现的目标的更多信息?如果您确实拥有字段名称,那么您的其余代码会是什么样子?
  • 我需要字段名和getter的值来验证和重新格式化..
  • 我不明白你想要什么,但如果你需要获取方法名称,我发现关于反射 api 的问题是 link

标签: java methods field getter


【解决方案1】:

使用getMethods获取emp的所有公共方法

然后选择getXXX方法并调用它

        Emp emp = new Emp();
        emp.setAddress("myAdress");
        emp.setAge(20);
        emp.setFirstName("myFirstName");
        emp.setLastName("myLastName");
        Class clz = emp.getClass();

        Method[] methods = clz.getMethods();
        for (Method method : methods) {
            String methodName = method.getName();
            if (!Objects.equals(methodName, "getClass")
                    && methodName.startsWith("get")
                    && methodName.length() > 3
                    && method.getParameterTypes().length == 0) {

                String field = methodName.substring(3, 4).toLowerCase() + methodName.substring(4);
                Object value = method.invoke(emp);
                System.out.println("field:" + field + ",value:" + value);
            }
        }

你也可以使用getDeclaredFields获取所有私有字段

按字段查找getXXX方法

        Field[] fields = clz.getDeclaredFields();
        for (Field field : fields) {
            String fieldName = field.getName();
            String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            try {
                Method method = clz.getMethod(methodName);
                Object value = method.invoke(emp);
                System.out.println("field:" + fieldName + ",value:" + value);
            } catch (NoSuchMethodException e) {
                System.out.println("no such method:" + methodName);
            }
        }

【讨论】:

    【解决方案2】:

    您可以使用 Java 反射。但是从 getter 获取字段名称可能不是一个好的设计,因为 getter 可能没有字段支持。考虑下面的吸气剂。

    public int getExp(){
        return today-joiningDate();
    }
    

    这没有字段支持。

    相反,如果你只想要字段名称和值,你可以实现如下。

    Class class1 = employee.getClass();
    Field[] fields= class1.getDeclaredFields();
        for(Field field:fields){
            try {
                field.setAccessible(true);
                System.out.println(field.getName()+":"+field.get(bean));
            } catch (IllegalArgumentException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      注释是一种选择。

      public @interface MyField {
          String fieldName() default "";
      }
      

      并在你的方法上使用它

      @MyField("firstName")
      getFirstName(){
         ...
      }
      

      然后通过反射获取fieldName。我认为这种方式比从方法名称生成字段名称更灵活。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-26
        • 2019-08-16
        • 2013-02-03
        • 1970-01-01
        • 1970-01-01
        • 2021-08-24
        • 1970-01-01
        相关资源
        最近更新 更多