Java type sûr égal()


Pourquoi n'y a-t-il pas de type-safe equals() en Java? Je pense que cela aiderait à détecter certaines erreurs pendant la compilation au lieu d'une erreur d'exécution ultérieure.

Comme exemple trivial considérons ceci:

class Person {
    Integer birthYear;
} 

class Car {
    Long releaseYear;
}

Avoir une méthode pour prendre une Personne et une collection de Voitures et supposer énumérer toutes les Voitures libérées la même année que la personne est née pourrait finir par utiliser:

if (person.birthYear.equals(car.releaseYear)) {
...magic happens...
}

Mais aucune magie ne se produirait jamais en utilisant cela. Même si les champs sont du même type lors de la création de le code, soit pourrait être modifié à un moment ultérieur sans obtenir d'erreur de compilation sur le code de comparaison.

Quelle serait la meilleure pratique pour éviter ce genre de problèmes?

Author: Nayuki, 2016-03-10

1 answers

De par sa conception, la méthode equals() de Java prend un Object afin que vous puissiez créer une collection hétérogène d'objets et les comparer les uns aux autres pour l'égalité.

Par exemple, vous pourriez avoir une liste d'objets arbitraires:

List<Object> lst = new ArrayList<>();
lst.add("abc");
lst.add(123);  // Integer
lst.add(456L);  // Long

Alors le fait que equals() prenne un Object signifie que vous pouvez implémenter:

void indexOf(List<Object> lst, Object target) {
    for (int i = 0; i < lst.size(); i++) {
        if (lst.get(i).equals(target))
            return i;
    }
    return -1;
}

Pour répondre spécifiquement à votre préoccupation, la seule façon d'être "sûr de type" est de définir un nouveau nom de méthode comme strictEquals(), et d'implémenter uniquement le paramètre avec votre type, pas le type Object. Par exemple:

class Person {
    boolean strictEquals(Person other) { ... }
}

class Car {
    boolean strictEquals(Car other) { ... }
}

En ce qui concerne votre utilisation de Integer et Longcomme champs, ne le faites pas. Utilisez plutôt les types primitifs int et long, et utilisez l'opérateur == pour comparer les valeurs. Cela présente un certain nombre d'avantages, comme de meilleures performances, pas de NullPointerException, et la possibilité de comparer correctement int à long (alors que Integer.equals(Long) retournera toujours false en raison de différents types, même si les objets ont la même valeur numérique).

 2
Author: Nayuki, 2016-03-10 17:24:33