簡體   English   中英

使用 pojo/java bean 的 getter 方法獲取屬性/字段名稱?

[英]Getting a property/field name using getter method of a pojo/java bean?

我有一個下面的類,我需要使用 java 反射從 getter 方法中獲取字段名稱。 是否可以使用 getter 方法獲取字段名稱或屬性名稱?

class A {

    private String name;
    private String salary;

    // getter and setter methods
}

我的問題是:我可以通過 getter 方法獲取字段/屬性名稱嗎? 如果我使用 getName(),我可以獲得 name 屬性嗎? 我需要 name 屬性但不需要它的值。 是否可以通過java反射?

是的,它是 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;
}

反射實用程序庫提供了一種以類型安全的方式確定屬性(名稱)的方法。 例如通過使用 getter 方法:

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

在這種情況下, propertyName的值將是"salary"

免責聲明:我是reflection-util庫的作者之一。

僅僅刪除“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));
}

您無法使用反射檢查代碼的作用。

您可以假設getName()方法讀取名為name的字段並且不執行其他任何操作。 但是,沒有要求這樣做。 例如,字段名稱可能是m_name_namenameField或者甚至不是字段。

你可以

Field[] declaredFields = A.class.getDeclaredFields();
        for(Field f:declaredFields){
            System.out.println(f.getName());
        }

如果您的 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
        }
    }

使用反射 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());
    }
}

您應該通過該方法訪問。 目前,getter 將返回成員name但將來可能會發生變化 它可以從數據庫或網絡服務懶惰地實例化它,從名字/姓氏等構建它。 name字段很可能不存在。

所以總是通過方法(甚至通過反射)

如果你知道方法的名字,你只需要去掉“get”,把后面的字母轉成小寫,就不需要反射了。

如果 getter 方法 (getName()) 返回名稱與“name”不同的屬性,則無法從該方法的名稱中獲取該屬性的名稱。

如果您不知道方法的名稱,則可以通過反射獲得所有方法,也可以獲得所有名稱的屬性。

您可以使用@FieldNameConstants @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"

嘗試以下

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方法用於從程序方法或數據庫中動態檢索數據。 它將僅反映值而不是值的屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM