1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
`java.util.IdentityHashMap` uses reference equality to compare keys. This is
[in violation of the contract of `java.util.Map`](http://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/IdentityHashMap.html),
which states that object equality (the keys' `equals` methods) should be used
for key comparison. This peculiarity can lead to confusion and subtle bugs,
especially when the two types of maps are used together. This check attempts to
reduce confusion between these two very different kinds of maps in a few ways:
1. An `IdentityHashMap`'s reference-equality behavior would be surprising if
its declared type was `java.util.Map`. The type of an `IdentityHashMap` is
required to be explicit, i.e., `IdentityHashMap` should not be upcast to
`Map`.
1. `IdentityHashMap`'s `equals` method will only compare equal to a `Map` if
the keys of both are the same instances. This makes little sense for an
object-equality map, so `IdentityHashMap.equals()` should only be used to
compare to other `IdentityHashMap`s.
1. The semantics of `Map` and `IdentityHashMap` are different enough that they
should be considered different, incompatible types. Converting one to the
other is discouraged, as it is often a mistake.
```java
Map<String, String> bad(Map<String, String> aMap, IdentityHashMap<String, String> identityMap) {
// Don't assign an `IdentityHashMap` to a plain `Map`-typed variable
Map<String, String> myMap = identityMap;
// Don't use `IdentityHashMap`'s `equals` method with a `Map`
identityMap.equals(aMap);
// Don't convert between `IdentityHashMap` and `Map`
identityMap.putAll(aMap);
identityMap = new IdentityHashMap<>(aMap);
return identityMap;
}
```
```java
// Keep `IdentityHashMap`'s type information around so maintainers know when
// reference equality is being used.
IdentityHashMap<String, String> good() {
IdentityHashMap<String, String> identityMap = new IdentityHashMap<>();
// ...
return identityMap;
}
```
|