Java类型安全等于()

时间:2016-03-10 17:15:33

标签: java equals type-safety

为什么Java中没有类型安全的equals()?我认为这有助于在编译期间捕获一些错误,而不是以后的运行时错误。

作为一个简单的例子,考虑一下:

class Person {
    Integer birthYear;
} 

class Car {
    Long releaseYear;
}

有一个方法来接收一个人和汽车的集合,并假设列出该人出生的同一年发布的所有汽车可能最终使用:

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

但使用它不会发生任何魔法。即使在创建代码期间字段属于同一类型,也可以在以后更改这些字段,而不会在比较代码上出现编译错误。

避免这类问题的最佳做法是什么?

1 个答案:

答案 0 :(得分:3)

按照设计,Java的equals()方法采用Object,这样您就可以创建异构的对象集合,并将它们相互比较以实现相等。

例如,您可能有一个任意对象列表:

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

然后equals()采用Object意味着你可以实现:

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;
}

要特别回答您的问题,“类型安全”的唯一方法是定义一个新的方法名称,例如strictEquals(),并且只使用您的类型实现参数,而不是Object类型。例如:

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

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

关于您使用IntegerLong作为字段,不要这样做。请改用原始类型intlong,并使用==运算符来比较值。这具有许多优点,例如更好的性能,没有NullPointerException,并且能够正确地比较intlong(而Integer.equals(Long)将始终返回false,因为不同的类型,即使对象具有相同的数值)。