20

我有一个下面的类,我需要使用 java 反射从 getter 方法获取字段名称。是否可以使用 getter 方法获取字段名称或属性名称?

class A {

    private String name;
    private String salary;

    // getter and setter methods
}

我的问题是:我可以通过 getter 方法获取字段/属性名称吗?如果我使用 getName(),我可以获得 name 属性吗?我需要 name 属性,但不需要它的值。是否可以通过java反射?

4

11 回答 11

20

是的,这是 100% 可能的..

public static String getFieldName(Method method)
{
    try
    {
        Class<?> clazz=method.getDeclaringClass();
        BeanInfo info = Introspector.getBeanInfo(clazz);  
        PropertyDescriptor[] props = info.getPropertyDescriptors();  
        for (PropertyDescriptor pd : props) 
        {  
            if(method.equals(pd.getWriteMethod()) || method.equals(pd.getReadMethod()))
            {
                System.out.println(pd.getDisplayName());
                return pd.getName();
            }
        }
    }
    catch (IntrospectionException e) 
    {
        e.printStackTrace();
    }
    catch (Exception e) 
    {
        e.printStackTrace();
    }


    return null;
}
于 2012-11-22T14:14:58.983 回答
14

反射实用程序库提供了一种以类型安全的方式确定属性(名称)的方法。例如通过使用 getter 方法:

String propertyName = PropertyUtils.getPropertyName(A.class, A::getSalary);

在这种情况下, 的值propertyName将是。"salary"

免责声明:我是反射实用程序库的作者之一。

于 2018-10-24T11:54:51.360 回答
7

仅删除“get”或“is”前缀并将第一个字母小写是不够的。例如,getID 的适当 bean 名称将是 ID 而不是 iD。

获取 bean 名称的最简单方法是去掉 get 或 is 前缀,然后将结果传递给Introspector.decapitalize

这是我写的一个方法来做这件事:

private String getBeanName(String methodName)
{
    // Assume the method starts with either get or is.
    return Introspector.decapitalize(methodName.substring(methodName.startsWith("is") ? 2 : 3));
}
于 2015-04-07T19:38:51.063 回答
6

您无法使用反射检查代码的作用。

你可以假设一个getName()方法读取了一个被调用的字段name并且什么都不做。但是,没有要求这样做。例如,字段名称可能是m_name或甚至不是字段_namenameField

于 2012-11-02T09:45:08.520 回答
6

你可以

Field[] declaredFields = A.class.getDeclaredFields();
        for(Field f:declaredFields){
            System.out.println(f.getName());
        }
于 2012-11-02T09:47:22.767 回答
3

您可以使用lombok 的 @FieldNameConstants注释。

注释你的类:

import lombok.experimental.FieldNameConstants;
import lombok.AccessLevel;

@FieldNameConstants
public class FieldNameConstantsExample {
  private final String name;
  private final int rank;
}

在后台生成以下代码:

public class FieldNameConstantsExample {
  private final String name;
  private final int rank;
  
  public static final class Fields {
    public static final String name = "name";
    public static final String rank = "rank";
  }
}

因此,您可以通过以下方式访问属性名称:

FieldNameConstantsExample.Fields.name

这是字符串"name"

于 2021-06-25T15:00:20.093 回答
1

如果您的 bean 遵循 JavaBean 约定,那么您使用反射来获取所有“get”和“is”方法,并从检索到的方法名称中删除“get”或“is”前缀,并且您拥有字段名称。

更新

// Get the Class object associated with this class.
    MyClass myClass= new MyClass ();
    Class objClass= myClass.getClass();

    // Get the public methods associated with this class.
    Method[] methods = objClass.getMethods();
    for (Method method:methods)
    {
        String name=method.getName();
        if(name.startsWith("get") || name.startsWith("is"))
        {
           //...code to remove the prefixes
        }
    }
于 2012-11-02T09:45:01.403 回答
1

使用反射 API,可以按如下方式检索 POJO 字段。继承的类可能会在这里发现问题。

TestClass testObject= new TestClass().getClass();
Fields[] fields = testObject.getFields();
for (Field field:fields)
{
    String name=field.getName();
    System.out.println(name);
}

或者通过使用反射 API,还可以检索类中的所有方法并遍历它以查找属性名称(标准 POJO 方法以 get/is/set 开头)......这种方法对我来说适用于继承的类结构。

TestClass testObject= new TestClass().getClass();
Method[] methods = testObject.getMethods();
for (Method method:methods)
{
    String name=method.getName();
    if(name.startsWith("get"))
    {
        System.out.println(name.substring(3));
    }else if(name.startsWith("is"))
    {
        System.out.println(name.substring(2));
    }
}

然而,更有趣的方法如下:

在 Jackson 库的帮助下,我能够找到 String/integer/double 类型的所有类属性,以及 Map 类中的相应值。(全部不使用反射 api!

TestClass testObject = new TestClass();
com.fasterxml.jackson.databind.ObjectMapper m = new com.fasterxml.jackson.databind.ObjectMapper();

Map<String,Object> props = m.convertValue(testObject, Map.class);

for(Map.Entry<String, Object> entry : props.entrySet()){
    if(entry.getValue() instanceof String || entry.getValue() instanceof Integer || entry.getValue() instanceof Double){
        System.out.println(entry.getKey() + "-->" + entry.getValue());
    }
}
于 2017-03-22T21:51:52.790 回答
0

您应该通过该方法访问。目前 getter 会返回成员name但将来可能会改变。它可以懒惰地从数据库或 Web 服务实例化它,从名字/姓氏等构建它。该name字段很可能不存在。

所以总是通过方法(即使通过反射)

于 2012-11-02T09:47:12.237 回答
0

如果知道方法名,只需要去掉“get”,将后面的字母转换成小写,就不需要反思了。

如果 getter 方法 (getName()) 返回名称与“名称”不同的属性,则无法从方法名称中获取属性名称。

如果您不知道方法的名称,通过反射您可以获得所有方法,您也可以获得所有名称的属性。

于 2012-11-02T09:51:10.610 回答
-3

尝试以下

class A{

       private String name;
       private String salary;

   //getter and setter methods

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

       public void setSalary(String salary){
           this.salary = salary;

         }

        public String getName(){
          return name;
          }

        public String getSalary(){
          return salary;
          }

}

get方法用于从程序方法或数据库中动态检索数据。它将仅反映值而不是值的属性。

于 2012-11-02T11:35:51.120 回答