Java génériques Génériques étend de 2 interfaces
Comment voulez-vous faire ce travail:
public class Frankenstein<T extends IHuman, IMonster>{
}
Sans faire
public interface Weirdo extends Ihuman, IMonster{
}
Modifier
Pourquoi ça ne marche pas?
public <T> void mapThis(
Class<? extends MyClass<T>> key, Class<? extends T & IDisposable> value) {
}
Je suis compilateur de marquage de message Class<? extends T & IDisposable>
comme une Erreur.
- Double Possible de Java Génériques Wildcarding Avec Plusieurs Classes
Vous devez vous connecter pour publier un commentaire.
Reimeus l'a déjà souligné que ce que vous demandez dans votre montage n'est pas possible. J'aimerais développer un peu pourquoi.
On pourrait penser que vous pouvez utiliser les éléments suivants:
En fait, c'est ce qui est venu à mon esprit quand j'ai vu ce post. Mais cela donne effectivement une erreur de compilateur:
Pour m'aider à expliquer pourquoi, je voudrais citer un Oracle Blogs post par Victor Rudometov sur cette erreur:
Les raisons de cette restriction sont explorées dans un étroitement liées post: Pourquoi ne puis-je pas utiliser un argument de type dans un paramètre de type, avec de multiples limites?
Pour résumer, la restriction a été imposée afin de "s'opposent à certaines situations délicates de venir à l'existence" (JLS §4.9).
Ce genre de situations embarrassantes? Une réponse par Chris Povirk décrit un:
Chris a aussi points à Soleil bug 4899305, qui était un bug contestation de cette restriction de langue. Il a été fermé parce que ne sera pas Corrigé avec le commentaire suivant:
De sorte que ces sont les raisons de la restriction. L'adressage des méthodes génériques spécifiquement (ce que votre question concerne), je voudrais en outre souligner que l'inférence de type, en théorie, la cause de ces limites inutile de toute façon.
Si nous réexaminer le type des paramètres déclarés dans l'hypothétique signature ci-dessus:
En supposant que l'appelant n'est pas de spécifier explicitement
T
etU
, cela peut être réduit à ce qui suit:Ou tout simplement cette (différence subtile, mais c'est un autre sujet):
C'est parce que
T
n'ont pas de limites, pour n'importe quel type d'arguments sont passés,T
peut toujours résoudre àObject
à tout le moins, et alors peutU
.Nous allons revenir en arrière et dire
T
est bornée:Cela peut être réduite de la même façon (
Foo
pourrait être une classe ou une interface):Basant sur ce raisonnement, la syntaxe que vous essayez d'atteindre est inutile autant que la restriction de l'appelant à plus d'arguments spécifiques.
Pré-Java 8 addendum:
Avant Java 8, il y est un cas d'utilisation pour ce que vous essayez de faire. En raison d'une limitation de la façon dont le compilateur déduit méthode générique paramètres de type, mon raisonnement ci-dessus pour sortir de la fenêtre. Prendre la méthode générique:
C'est une erreur de débutant d'essayer de faire une méthode qui prend deux paramètres de la "même type". Bien sûr, c'est inutile, parce que de la façon dont l'héritage fonctionne:
Ici,
T
est déduit d'Object
- ce qui correspond à plus tôt de raisonnement sur la simplification de lamapThis
des paramètres de type. Vous devez spécifier manuellement les paramètres de type de commande à atteindre le type de vérification:Cependant, et c'est là que votre cas d'utilisation commence à rentrer, c'est une autre affaire avec plusieurs paramètres de type d'échelonnement des limites:
Maintenant cet appel erreurs:
Les tables ont tourné - nous avons manuellement détendre les paramètres de type pour la compiler:
Ceci se produit en raison de la limitation façon dont le compilateur déduit de la méthode des paramètres de type. Pour cette raison, ce que tu voulais faire aurait effectivement eu une demande en limitant les arguments de l'appelant.
Toutefois, ce problème semble avoir été résolu dans Java 8, et
MyClass.foo("asdf", 42)
maintenant se compile sans erreur, (grâce à un Régent pour le signaler).MyClass.foo("asdf", 42)
ne donne pas d'erreur de compilation avec<T, U extends T>
limites dans Java 8.J'ai juste pensé que je voudrais partager mon hack que j'utilise dans ces (assez rare) situations:
Donc, en exigeant le même objet pour chacune des limites en essayant de vous satisfaire, vous obtenez le type de compilation vérification et de l'objet unique qui s'occupe de tout. Certes, il est un peu bête de passer le même objet, pour chaque paramètre, mais je le fais dans mon "intérieur" code en toute sécurité et confortablement.