A DESCRIPTION OF THE PROBLEM :
if (e1 == null) {
return false;
}
modify this:
if (e1 == null || e2 == null ) {
return false;
}
Comments
The behavior of Objects.equals(e1, e2) is deliberate in that if e1 != null, it delegates to e1.equals(e2). See JDK-8223112 and links to CSR and mailing history for more information. As such, Objects.deepEquals should have equivalent behavior for array elements. Closing as Not An Issue.
15-04-2022
This seems like an easy optimization, but it's actually a subtle behavior change. The e2 reference is not checked for null, which means that the evaluation is delegated to e1.equals(). It is generally bad style to have something compare equal to null, but it is possible and this is the current behavior. For example, here is a class that contains an int, and it considers a Box containing zero to be equal to null:
record Box(int i) {
public boolean equals(Object o) {
return (i == 0 && o == null) || (o instanceof Box other && i == other.i);
}
}
# as expected
jshell> new Box(1).equals(null)
$78 ==> false
# also as expected
jshell> new Box(0).equals(null)
$79 ==> true
# also supported by Objects.equals
jshell> Objects.equals(new Box(0), null)
$80 ==> true
# but Objects.equals() is asymmetric, a consequence of the class's design decision
jshell> Objects.equals(null, new Box(0))
$81 ==> false
# current behavior of deepEquals
jshell> Objects.deepEquals(new Box[] { new Box(0) }, new Box[] { null })
$82 ==> true
# asymmetry also exposed here
jshell> Objects.deepEquals(new Box[] { null }, new Box[] { new Box(0) })
$83 ==> false
While the current behavior is somewhat odd, I'm reluctant to change it without further thought.
14-04-2022
The source code can be found at:
https://hg.openjdk.java.net/jdk8/jdk8/jdk/file/bedc29a6d074/src/share/classes/java/util/Arrays.java#l4236
https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/Arrays.java#L4621