简体   繁体   English

使用 pojo/java bean 的 getter 方法获取属性/字段名称?

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

I have a below class and i need to get field name from getter method using java reflection.我有一个下面的类,我需要使用 java 反射从 getter 方法中获取字段名称。 Is it possible to get field name or property name using getter method?是否可以使用 getter 方法获取字段名称或属性名称?

class A {

    private String name;
    private String salary;

    // getter and setter methods
}

My questions is: can i get field/property name by getter method?我的问题是:我可以通过 getter 方法获取字段/属性名称吗? If I use getName(), can I get name property?如果我使用 getName(),我可以获得 name 属性吗? I need name property but not its value.我需要 name 属性但不需要它的值。 Is it possible through java reflection?是否可以通过java反射?

yes it's 100% possible..是的,它是 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;
}

The reflection-util library provides a way to determine the property (name) in a type-safe manner.反射实用程序库提供了一种以类型安全的方式确定属性(名称)的方法。 For example by using the getter method:例如通过使用 getter 方法:

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

The value of propertyName would be "salary" in this case.在这种情况下, propertyName的值将是"salary"

Disclaimer : I'm one of the authors of the reflection-util library.免责声明:我是reflection-util库的作者之一。

It's not exactly good enough to just remove the "get" or "is" prefix and lower case the first letter.仅仅删除“get”或“is”前缀并小写第一个字母是不够的。 For example, the appropriate bean name for getID would be ID and not iD.例如,getID 的适当 bean 名称将是 ID 而不是 iD。

The easiest way to get the bean name is to lop off the get or is prefix and then pass the result into Introspector.decapitalize .获取 bean 名称的最简单方法是去掉 get 或 is 前缀,然后将结果传递给Introspector.decapitalize

Here's a method I wrote to do this very thing:这是我写的一个方法来做这件事:

private String getBeanName(String methodName)
{
    // Assume the method starts with either get or is.
    return Introspector.decapitalize(methodName.substring(methodName.startsWith("is") ? 2 : 3));
}

You cannot inspect what code does by using reflection.您无法使用反射检查代码的作用。

You can assume that a getName() method read a field called name and does nothing else.您可以假设getName()方法读取名为name的字段并且不执行其他任何操作。 However there is no requirement for it to so.但是,没有要求这样做。 eg the field name might be m_name or _name or nameField or not even be a field.例如,字段名称可能是m_name_namenameField或者甚至不是字段。

You can你可以

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

If your bean's follow JavaBean conventions then you use reflection to get all the "get" and "is" methods and remove "get" or "is" prefixes from the retrieved method names and you have the field names.如果您的 bean 遵循 JavaBean 约定,那么您使用反射来获取所有“get”和“is”方法并从检索到的方法名称中删除“get”或“is”前缀,并且您拥有字段名称。

Update更新

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

Using reflections API, POJO fields can be retrieved as below.使用反射 API,可以检索 POJO 字段,如下所示。 Inherited class may find an issue here.继承的类可能会在这里发现问题。

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

Or by using Reflections API, one can also retrieve all methods in a class and iterate through it to find the attribute names (standard POJO methods start with get/is/set) ... This approach worked for me for Inherited class structure.或者通过使用反射 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));
    }
}

However a more interesting approach is below:然而,更有趣的方法如下:

With the help of Jackson library, I was able to find all class properties of type String/integer/double, and respective values in a Map class.在 Jackson 库的帮助下,我能够找到 String/integer/double 类型的所有类属性,以及 Map 类中的相应值。 ( all without using reflections api! ) 全部不使用反射 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());
    }
}

You should access through the method.您应该通过该方法访问。 At the moment the getter would return the member name , but that could change in the future .目前,getter 将返回成员name但将来可能会发生变化 It could lazily instantiate this from a database or webservice, built it from a firstname/surname etc. The name field could quite likely not exist.它可以从数据库或网络服务懒惰地实例化它,从名字/姓氏等构建它。 name字段很可能不存在。

So always go through the method (even via reflection)所以总是通过方法(甚至通过反射)

If you know the name of the method, you only need to remove "get" and convert to lower letter the following letter, so you don´t need reflection.如果你知道方法的名字,你只需要去掉“get”,把后面的字母转成小写,就不需要反射了。

If the getter method (getName()) returns a property with different name than "name", you can´t obtain the property's name from the method´s name.如果 getter 方法 (getName()) 返回名称与“name”不同的属性,则无法从该方法的名称中获取该属性的名称。

If you don´t know the name of the method, by reflection you can obtain all methods and you can obtain all name´s properties too.如果您不知道方法的名称,则可以通过反射获得所有方法,也可以获得所有名称的属性。

You can use lombok's @FieldNameConstants annotation.您可以使用@FieldNameConstants @FieldNameConstants注释。

Annotate your class:注释你的类:

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

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

which produces following code on the background:它在后台生成以下代码:

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

So you can access property name in a following way:因此,您可以通过以下方式访问属性名称:

FieldNameConstantsExample.Fields.name

which is string "name"这是字符串"name"

Try the following尝试以下

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

} }

The get method is used to retrieve data dynamically from program method or from database. get方法用于从程序方法或数据库中动态检索数据。 It will reflect only values not property of the value.它将仅反映值而不是值的属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 名称下的bean属性没有可用的getter方法 - No getter method available for property for bean under name 使用getter方法时出现错误(HttpMessageNotWritableException:无法写入JSON:bean类的无效属性'') - I am getting an error (HttpMessageNotWritableException: Could not write JSON: Invalid property '' of bean class) when using getter method Bean属性不可读或具有无效的getter方法 - Bean property is not readable or has an invalid getter method 最终字段名称的Getter方法 - Getter method for final field name Bean类[java.util.ArrayList]的无效属性`xyz`:Bean属性&#39;xyz&#39;不可读或具有无效的getter方法 - Invalid property `xyz` of bean class[java.util.ArrayList]: Bean property 'xyz' is not readable or has an invalid getter method 如何将 JSON 字段名称转换为 Java bean class 属性与 Z7930C951E604E461E85226AED9 - How to convert JSON field name to Java bean class property with Jackson 在 micronaut 2.1.2 中获取 POJO 属性名称 - Getting the POJO property name in micronaut 2.1.2 Java bean的Typesafe属性名称 - Typesafe property name for a java bean Bean 属性“categoryName”不可读或具有无效的 getter 方法 - Bean property 'categoryName' is not readable or has an invalid getter method Bean 属性“dipartmantId”不可读或具有无效的 getter 方法: - Bean property 'dipartmantId' is not readable or has an invalid getter method:
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM