2 votes

Java stocke les conditions par type générique

J'ai lu Effective Java et j'ai décidé d'essayer de mettre en pratique ce que j'ai appris. J'essaie de créer efficacement un Multimap<?, Condition<?> > où le joker sera du même type pour la clé et la valeur, mais il s'agira de types différents et distincts.

Voici l'article du livre que j'ai sous les yeux : Article 29

Je n'essaie pas de le reproduire entièrement. Je réalise que la grande différence est que la clé ne représente pas directement la valeur comme dans le lien. Dans le mien, la clé représente le type générique de la valeur.

Je vais donc faire mmap.put(Class<Integer>, ConditionMapping<Integer>) quand je fais le get, je n'ai pas le type générique du ConditionMapping, donc j'obtiens l'avertissement de cast non vérifié.

J'ai une méthode get dont je veux qu'elle ait la signature <T> List<Condition <T> >(Class<T> type)

En raison de l'effacement de type, ma seule option est-elle de m'assurer que la condition.value est de type T et de construire une nouvelle liste d'objets ?

Je pourrais simplement ignorer l'avertissement de distribution non cochée, mais j'essaie de ne pas le faire. Des suggestions ? Des conseils ? Des astuces ?

1voto

finnw Points 24592

Si vous faites en sorte que votre interface étende Multimap<Void, Condition<?>> il permet à votre utilisateur d'appeler certaines des méthodes qui ne dépendent pas de la sécurité de type (par exemple containsKey) mais pas d'ajouter des entrées (en contournant vos méthodes proxy à contrôle de type) à moins qu'il n'utilise des casts non vérifiés.

interface ConditionMapBase<T> extends Multimap<T, Condition<?>> {
}
interface ConditionMap extends ConditionMapBase<Void> {
    <T>boolean putCondition(T key, Condition<T> value);
    <T>Collection<Condition<T>> getConditions(T key);
}
class ConditionMapImpl
extends ForwardingMultimap<Void, Condition<?>>
implements ConditionMap {

    ConditionMapImpl() {
        delegate = HashMultimap.create();
    }
    @SuppressWarnings("unchecked")
    @Override
    protected Multimap<Void, Condition<?>> delegate() {
        return (Multimap<Void, Condition<?>>) (Multimap<?, ?>) delegate;
    }
    private final Multimap<Object, Condition<?>> delegate;
    @SuppressWarnings("unchecked")
    @Override
    public <T> Collection<Condition<T>> getConditions(T key) {
        return (Collection<Condition<T>>) (Collection<?>) ((ConditionMapBase<T>) this).get(key);
    }
    @SuppressWarnings("unchecked")
    @Override
    public <T> boolean putCondition(T key, Condition<T> value) {
        return ((ConditionMapBase<T>) this).put(key, value);
    }
}

1voto

OrangeDog Points 7380

Il n'y a aucun moyen d'exprimer que les deux jokers doivent capturer le même type. Voir cette question pour une situation similaire et un certain nombre de solutions possibles.

0voto

Kajetan Abt Points 747

Vous pourriez créer une MyClass et lui passer votre propre type, et écapsuler le Multimap à l'intérieur de celle-ci. Les impossibilités des modèles en Java peuvent souvent être résolues en ajoutant une autre couche, pour ainsi dire, et en créant une classe autour de ce que vous voulez vraiment, puisque vous pouvez obtenir un type "T" de cette façon, que vous pouvez ensuite utiliser pour les listes ou les cartes, et garantir qu'il est le même pour plusieurs modèles à partir de là.

0voto

mncl Points 53

Cela pourrait être un pas dans la bonne direction.

<Multimap<Class<?>, Condition<?>>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X