web-dev-qa-db-fra.com

Obtenir un nom de propriété/champ en utilisant la méthode getter d’un bean pojo/Java?

J'ai une classe ci-dessous et j'ai besoin d'obtenir le nom du champ à partir de la méthode getter à l'aide de la réflexion Java . Est-il possible d'obtenir le nom du champ ou le nom de la propriété à l'aide de la méthode getter?

class A {

    private String name;
    private String salary;

    // getter and setter methods
}

Ma question est la suivante: puis-je obtenir le nom du champ/propriété par la méthode getter? Si j'utilise getName (), puis-je obtenir la propriété name? J'ai besoin de la propriété name mais pas de sa valeur. Est-ce possible par réflexion Java?

11
user1016403

oui c'est 100% possible ..

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;
}
16
Vishal Zanzrukia

Il ne suffit pas de supprimer simplement le préfixe "get" ou "is" et la minuscule la première lettre. Par exemple, le nom de bean approprié pour getID serait ID et non pas iD.

Le moyen le plus simple d'obtenir le nom du bean consiste à supprimer le préfixe get ou is, puis à transférer le résultat dans Introspector.decapitalize .

Voici une méthode que j'ai écrite pour faire cette chose même:

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

Vous ne pouvez pas inspecter le code en utilisant la réflexion.

Vous pouvez supposer qu'une méthode getName() lit un champ appelé name et ne fait rien d'autre. Cependant, il n’est pas nécessaire de le faire. par exemple. le nom du champ peut être m_name ou _name ou nameField ou même ne pas être un champ.

5
Peter Lawrey

La bibliothèque reflect-util fournit un moyen de déterminer la propriété (nom) d'une manière sûre pour le type . Par exemple, en utilisant la méthode getter:

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

La valeur de propertyName serait "salary" dans ce cas.

Disclaimer: Je suis l’un des auteurs de la bibliothèque { réflexion-util }.

2
Benedikt Waldvogel

Si votre bean respecte les conventions JavaBean, utilisez la réflexion pour obtenir toutes les méthodes "get" et "is" et supprimez les préfixes "get" ou "is" des noms de méthodes extraits et vous avez les noms de champs.

Mettre à jour

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

Vous devriez accéder via la méthode. À l'heure actuelle, le getter renvoie le membre name, mais cela pourrait changer à l'avenir . Il pourrait par instancier l'instancier d'une base de données ou d'un service Web, le construire à partir d'un prénom/nom, etc. Le champ name pourrait très probablement ne pas exister.

Alors toujours passer par la méthode (même via la réflexion)

0
Brian Agnew

Vous pouvez

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

À l'aide de l'API de réflexion, les champs POJO peuvent être récupérés comme ci-dessous. La classe héritée peut trouver un problème ici.

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

Ou en utilisant l'API Reflections, on peut également extraire toutes les méthodes d'une classe et y parcourir les noms des attributs (les méthodes POJO standard commencent par get/is/set) ... Cette approche a fonctionné pour moi pour la structure de classe Inherited.

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

Cependant, une approche plus intéressante est ci-dessous:

Avec l'aide de la bibliothèque Jackson, j'ai pu trouver toutes les propriétés de classe de type String/integer/double et les valeurs correspondantes dans une classe Map. ( le tout sans utiliser de réflexions 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());
    }
}
0
Amit Kaneria

Si vous connaissez le nom de la méthode, il vous suffit de supprimer "get" et de convertir en lettre inférieure la lettre suivante, afin que vous n’ayez pas besoin de réflexion. 

Si la méthode getter (getName ()) renvoie une propriété dont le nom est différent de "name", vous ne pouvez pas obtenir le nom de la propriété à partir du nom de la méthode.

Si vous ne connaissez pas le nom de la méthode, vous pouvez obtenir par réflexion toutes les méthodes et toutes les propriétés de name.

0
Chuidiang