J'ai écrit cette fonction utilitaire: J'ai copié l'idée de Mon problème est que si l'appelant obtient le type de type, aucune exception n'est lancée tant que l'appelant a essayé d'obtenir un objet de la liste. Idéalement, j'aimerais jeter un Y a-t-il des astuces que je peux utiliser pour vous assurer que l'appelant ne se retrouve pas avec une liste non valide? < / p> mais réellement lambdaj semble Pour faire ce que je voulais, alors je suppose que je vais l'utiliser. Merci Mike! P> Disclaimer: strong> lambdaj em> ( @ googlecode | @github ) - Ce projet n'est plus maintenu depuis le Libération de jdk8 ( JSR 335 , Jep 126 ). P> p> Classcastexception code> à partir de la méthode CODE> PLUCK CODE>. Cependant, je ne vois pas un moyen d'accéder au type de la liste sur le temps d'exécution. P>
8 Réponses :
Qu'entendez-vous par liste non valide? Si vous voulez dire qu'ils essaient de le jeter à quelque chose, il ne réussit pas alors à changer la déclaration à Je suis confondu par le Public Static
Cependant, je ne vois pas un moyen d'accéder au type de liste au moment de l'exécution. Code> Commentaire. Cependant, si je vous comprends correctement, il n'y a pas de "type" au moment de l'exécution car les génériques de Java sont mis en œuvre par "Erasure". Cela signifie que le compilateur vérifie lors de la compilation qu'il fonctionne, puis le transforme en moulages réguliers comme nous avions avant les génériques. Ceci était nécessaire qu'ils ont ressenti de la compatibilité en arrière et en avant. P>
Je ne sais pas ce que vous demandez, mais vous pouvez essayer:
Class c = list.get(0).getClass(); if (!c.equals(Person.class)) throw new ClassCastException();
Vous pouvez lancer la liste sur un java.lang.reflect.paramétratedtype code> et vérifier que le tableau renvoyé par
getactualtypearguments () code> contient la classe dont vous avez besoin. Autre que cela, vous n'êtes pas de chance. P>
Cela ne fonctionnerait que si la liste qu'il a eu était, par exemple, une sous-classe définie comme StringList étendra l'arraylist
New ArrayList
Pourquoi ne définissez-vous pas la signature comme celle-ci:
public static <T, U> List<T> pluck(String fieldName, Class<T> fieldType, List<U> list);
"Vous empêchez donc une autre source d'erreur (le client fournissant une liste contenant des objets de types différents)" Il n'empêcherait rien; La façon dont vous l'avez écrite, cela accepterait toute liste.
@newacct Il accepterait simplement des listes qui contiennent des objets d'un type spécifique. Vous ne pouvez donc pas passer une liste contenant différents types d'objets. La signature originale accepterait des listes non génériques, ce qui augmenterait la probabilité d'objets étant transmis en ce qui ne contient pas le champ.
@Newacct Vous pouvez simplement ne pas réussir le type 'List'. Mais vous devriez passer une liste
Vous devez utiliser des génériques pour le paramètre de type et transmettre l'objet de la classe du type de retour: Généralement, lorsque vous obtenez un avertissement sur une mise en forme dangereuse sur un paramètre de type, Vous devriez voir si vous pouvez le remplacer par un appel à classe.cast code> p> p>
Vous pouvez modifier votre signature en suivant:
public static <T, F> List<F> pluck(String fieldName, Class<F> fieldType, List<T> list, Class<T> listType)
Vous pouvez essayer celui donné par Google Collections Bibliothèque au lieu de la maintenance d'une nouvelle: Collections2.Transformez comme celle-ci
Collection<Y> yourCollection... ... Collection<X> expected = Collections2.transform(yourCollection, new Function<Y, X>() { public X apply(Y element) { return element.getX(); } }
Avec la bibliothèque de collections Guava de Google, vous pouvez utiliser Collections2.Transform () code>
.
entité code>, votre classe peut implémenter / étendre ceci. p> xxx pré> xxx pré> maintenant Vous pouvez récupérer une liste de chacun Entity Code> S IDS. P>
public static <T,F> List<F> pluck(String fieldName, Class<F> fieldType,
List<T> list, Class<T> listType) throws NoSuchFieldException,
IllegalAccessException, IllegalArgumentException {
Field f = listType.getDeclaredField(fieldName);
f.setAccessible(true);
return list.stream().map(e -> {
try { return fieldType.cast(f.get(e)); } catch (Exception e1) { return null; }
}).collect(Collectors.toList());
}
Lambdaj fait cela et bien plus encore, de manière sûre. C'est une de mes bibliothèques préférées.
list.get.get (0) .getclass () code> pourrait ne pas vous procurer la bonne classe. Si
list.get.get (0) code> est null qu'il va crancer. En outre, les éléments ultérieurs de la liste code> code> peuvent ne pas être des instances de
list.get.get (0) code> s classe
Et pour cueillir également des champs de classe privée, vous voudrez peut-être faire ceci: champ f = listtype.getdeclaredfield (Nom de terrain); f.Setaballest (vrai); au lieu de faire champ f = listtype.getfield (nom de terrain);