Primordial “est synonyme de” méthode: comment faire pour déterminer le type du paramètre?
Je suis en train de remplacer equals
méthode d'une classe paramétrée.
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Tuple))
return false;
Tuple<E> other = (Tuple<E>) obj; //unchecked cast
if (!a0.equals(other.a0) && !a0.equals(other.a1)) {
return false;
}
if (!a1.equals(other.a1) && !a1.equals(other.a0)) {
return false;
}
return true;
}
Comment puis-je m'assurer que <E>
de la other
objet est le même que this
?
- BTW, n'est-ce pas logique implique que "a","a" et "a","b" sont égaux? Ne serait-il pas plus simple d'écrire "si a0=a0 et a1=a1 ou a0=a1 et a1=a0..."
- Si vous permettez à votre a0 et a1 est nul, assurez-vous d'ajouter le vérifie.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez le faire en conservant une référence à
Class<E>
type. Cependant, à mon avis, tests d'égalité devrait être sur les valeurs les objets représentent plutôt que les types de béton les valeurs se font.Un exemple classique est l'Collections de l'API par exemple.
new ArrayList<String>().equals(new LinkedList<Object>())
retournetrue
. Bien que ces ont complètement différents types, ils représentent la même valeur, à savoir "vide de collection".Personnellement, si deux
Tuple
s qui représentent les mêmes données (par exemple,("a", "b")
) ne soit pas l'égalité, parce que l'un est de typeTuple<String>
tandis que l'autre estTuple<Object>
?En raison de l'effacement, vous ne pouvez pas. À propos de les meilleures que vous pourriez faire est de stocker dans le tuple de la classe, le type de plan pour le n-uplet de maintenir un "java.lang.Class" membre de champ. Ensuite, vous pouvez comparer ces champs assurez-vous que le n-uplet de la classe est la même types.
Aussi, voir ce fil:
Quel est l'équivalent du C++ Paire<L,R> en Java?
Il serait utile si vous afficher plus au sujet de votre classe. Je pense à la décoché exprimés et le nombre de champs que vous assimiler signifie qu'il doit être Tuple<E,F> non?
EDIT: voici un utile Paire de classe je l'utilise régulièrement (vous pouvez adapter votre Tuple de la classe si nécessaire). Remarque, semblables à des suggestions faites par d'autres, cette classe permet à l'contenues membres de décider de la question de l'égalité. Votre cas d'utilisation est ce qui doit déterminer si l'égalité est vraiment basé sur le type de contenus membres.
Je viens de tomber sur ce problème moi-même, et en mon particulier les cas, je n'ai pas besoin de connaître le type E.
Par exemple:
Dans le code ci-dessus, il n'est pas décochée exprimés en raison de l'utilisation
Example<?>
. Le paramètre de type caractère '?' sauve la journée.Malheureusement, vous ne pouvez pas le faire au moment de la compilation; l'information est allé. Telles sont les conséquences de type erasure. Une alternative consiste à stocker le paramètre comme une
Class
instance, puis le chercher plus tard.Depuis les génériques sont effacés au moment de la compilation, fondamentalement, vous ne pouvez pas. Au moment de l'exécution, tout paramètre de type est parti, et aussi loin que la JVM est concerné, ils sont exactement les mêmes à tous égards.
La façon de contourner ce problème est de stocker un
Class
champ qui représente le type, et de créer l'objet avec ce type dans le constructeur.Un échantillon constructeur:
Ou vous pouvez utiliser une usine:
Les suggestions de conserver une référence à
E
's type avec unClass
objet semblent inefficace (que beaucoup de inutile de références à uneClass
de prendre de la mémoire) et inutile pour votre problème.Il n'est pas généralement vrai que
Foo<Bar>
etFoo<Baz>
devrait être inégale. Si vous n'avez pas besoinE
. Et, dans le code que vous avez écrit, vous n'avez même pas besoin de compiler. Tout simplement jeté àTuple<?>
, car c'est vraiment tout ce que vous savez à propos deTuple
à ce point. - Il encore compile tous et à toutes.Si vous êtes passé
Tuple
s avec les données de deux sauvagement différents types, ces éléments ne seront pasequals
, et votre méthode sera de retourfalse
, comme souhaité. (On l'espère-dépend de ces types de mise en œuvre deequals
sainement.)Class
objet doit être conservé par le chargeur de classe/JVM de toute façon, la seule la mémoire supplémentaire que vous souhaitez utiliser est d'environ un supplément de quatre octets pour un pointeur (8 pour les systèmes 64 bits).Hors-sujet - rendez-vous compte, en fonction de votre mise en œuvre, le n-uplet(a0, a1) est égal à n-uplet(a1, a1)? Je pense que c'est pas ce que vous voulez...
Sur le sujet, comme d'autres l'ont dit, l'effacement rend cela impossible. Mais vous devriez reconsidérer pourquoi vous voulez cette - la vérification de l'égalité se produit uniquement lors de l'exécution, et les génériques sont seulement au moment de la compilation. Conceptuellement, une variable a des paramètres génériques, mais un objet ne le fait pas. Ainsi, lorsque vous êtes en comparant l'égalité entre les objets, les paramètres génériques n'ont pas d'importance du tout; vous ne pouvez pas prendre toute action appropriée selon eux, au moment de l'exécution de toute façon.
Objet d'égalité et de paramètre générique co/contra-variance, sont deux orthogonaux préoccupations.
Je suis d'accord avec les commentaires ci-dessus, pourquoi ne le classe E doivent être égaux? et comment voulez-vous traiter les sous-classes de E?
De toute façon, étant donné que c'est ici un exemple de code qui peut vous aider:
Vous pouvez appeler t.getClass() pour obtenir des informations de classe sur le type de T (en supposant qu'il n'est pas nul, bien sûr.)
J'espère que cette aide.
Utiliser la réflexion. http://tutorials.jenkov.com/java-reflection/generics.html