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

使用pojo/Javabean的getter方法获取属性/字段名?,java,reflection,Java,Reflection,我有一个bellow类,需要使用java反射从getter方法获取字段名。 是否可以使用getter方法获取字段名或属性名 class A { private String name; private String salary; // getter and setter methods } 我的问题是:我可以通过getter方法获取字段/属性名吗?如果使用getName(),可以获取name属性吗?我需要name属性,但不需要它的值。可以通过java反射吗?如果您

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

class A {

    private String name;
    private String salary;

    // getter and setter methods
}

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

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

更新


您无法使用反射检查代码的功能


您可以假设
getName()
方法读取名为
name
的字段,而不执行其他操作。但是,没有要求它这样做。e、 g.字段名可能是
m\u name
\u name
nameField
或甚至不是字段。

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

因此,请始终使用该方法(即使是通过反射)

您可以

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

如果知道方法的名称,只需删除“get”并将下面的字母转换为小写字母,这样就不需要反射

如果getter方法(getName())返回的属性的名称与“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方法用于从程序方法或数据库中动态检索数据。它将只反映值,而不是值的属性。

是的,这是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;
}
公共静态字符串getFieldName(方法)
{
尝试
{
Class clazz=method.getDeclaringClass();
BeanInfo info=内省者.getBeanInfo(clazz);
PropertyDescriptor[]props=info.getPropertyDescriptors();
对于(PropertyDescriptor pd:props)
{  
if(method.equals(pd.getWriteMethod())| | method.equals(pd.getReadMethod()))
{
System.out.println(pd.getDisplayName());
返回pd.getName();
}
}
}
捕获(内省异常e)
{
e、 printStackTrace();
}
捕获(例外e)
{
e、 printStackTrace();
}
返回null;
}

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

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

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

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

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

TestClass testObject= new TestClass().getClass();
Fields[] fields = testObject.getFields();
for (Field field:fields)
{
    String name=field.getName();
    System.out.println(name);
}
或者通过使用Reflections 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库的帮助下,我能够在Map类中找到String/integer/double类型的所有类属性以及相应的值。(全部不使用反射api!)

TestClass testObject=newtestclass();
com.fasterxml.jackson.databind.ObjectMapper m=new com.fasterxml.jackson.databind.ObjectMapper();
Map props=m.convertValue(testObject,Map.class);
for(Map.Entry:props.entrySet()){
if(entry.getValue()instanceof String | | entry.getValue()instanceof Integer | | entry.getValue()instanceof Double){
System.out.println(entry.getKey()+“-->”+entry.getValue());
}
}
该库提供了一种以类型安全的方式确定属性(名称)的方法。 例如,通过使用getter方法:

String propertyName = PropertyUtils.getPropertyName(A.class, A::getSalary);
在这种情况下,
propertyName
的值将是
“salary”


免责声明:我是该库的作者之一。

如果您得到有用的答案…您应该接受:)这只给出了所有字段的列表,而不是与getter关联的字段。@Adam为此,您需要列出所有get方法,并使用该方法可以获取filedsIt这是OP想要的。我认为没有属性描述符是不可能的。名为ID的变量(和名为getID的getter)不遵循JavaBean命名约定。变量名称应以小写字母开头。@NamelessVoice,变量应以小写字母开头是正确的。然而,我们不是在讨论变量。我们在谈论财产。请参阅Javabean标准的第8.8节:我的错,我不知道这个边缘案例场景。如何将方法作为参数发送??getFieldName(cls.getProperty())将给出值如果属性名不同于去掉“get”并将其余部分去资本化,那么这将不起作用。例如,如果我有一个getName()getter,属性名为_name或m_name,那么您有一个名为
arg1
的字段,getter方法名为
getAge
(除了一个100%的pojo bean之外,可以认为是脏的),这已经不是100%可能了。如何使getName是作为参数发送到此方法的方法不要使用reflection util它通过临时依赖关系使用“不安全”并且不能在jdk>8上工作。@rumatoest:我不知道reflection util在jdk>8上不工作。你能在项目中提出一个问题吗?
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());
    }
}
String propertyName = PropertyUtils.getPropertyName(A.class, A::getSalary);