2017-02-08 3 views
0

J'ai une méthode qui prend un objet et une chaîne (la chaîne étant le nom d'un champ sur l'objet). Donc, j'obtiens le champ de la classe d'objet et j'utilise le champ field.get (objet) pour obtenir la valeur. Mais je veux attribuer cette valeur à n'importe quelle classe dans laquelle le champ a été défini. Y at-il un moyen de faire cette distribution sans avoir besoin d'utiliser @suppressWarnings ("non cochée")?Comment obtenir la classe d'un champ sur un objet générique lorsque le champ est référencé par le nom de la chaîne

Voici mon code. Je l'ai raccourci pour n'utiliser qu'un seul objet, mais l'original a utilisé une liste d'objets et retourne une carte avec les clés de la carte étant les valeurs des objets pour le champ et les valeurs de la carte étant l'objet.

public static <T1,T2> T2 getFieldValue(T1 obj, String fieldName){ 
    Field field = null; 
    T2 value = null; 
    try { 
     field = obj.getClass().getField(fieldName); 
    } catch (NoSuchFieldException e) { ... } 
    if (field != null){ 
     try { 
      value = (T2)field.get(obj); // <--- unchecked cast!!! 
     } catch (IllegalAccessException e) { ... } 
    } 
    return value; 
} 

Répondre

2

Je recommande en passant un argument pour la classe de T2 si possible. En passant dans le Class<T2> vous pouvez appeler la méthode cast. Cette méthode lancera un ClassCastException si la distribution n'est pas valide. Cela supprimera également les messages d'avertissement non contrôlés.

public static <T1, T2> T2 getFieldValue(T1 obj, String fieldName, Class<T2> cls) { 
    Field field = null; 
    T2 value = null; 
    try { 
     field = obj.getClass().getField(fieldName); 
    } catch (NoSuchFieldException e) { 
    } 
    if (field != null) { 
     try { 
      value = cls.cast(field.get(obj)); // <--- no unchecked cast!!! 
     } catch (IllegalAccessException e) { 
     } catch (ClassCastException e) { 
     } 
    } 
    return value; 
} 
+0

+1 pour utiliser 'Class.cast()', mais -1 pour les blocs catch vides. Il serait probablement bon d'attraper quelque chose comme 'ReflectiveOperationException' et de faire quelque chose de plus utile avec, même s'il est réenvoyé dans un' IllegalArgumentException' ou quelque chose. –

+0

Il est vrai que les exceptions devraient être traitées dans un sens; cependant, je les ai laissés vides car l'exemple original les a également laissés vides. La seule différence est que j'ai enlevé le "..." pour que le code compile. – DragonAssassin

+0

'value = cls.cast (field.get (obj));' n'est pas sûr. L'avertissement est simplement déplacé et supprimé. Cela donne une impression de code de sécurité alors que ce n'est pas le cas. Je préfère une distribution explicite avec un @ deleteWarnings explicite qui transmet le côté dangereux de la méthode. – davidxxx