为什么两个具有不同泛型类型的空 ArrayList 相等?

Why are two empty ArrayLists with different generic types equal?

我对 equals() 方法如何适用于 ArrayList 有疑问。下面的代码片段打印 true.

ArrayList<String> s = new ArrayList<String>();
ArrayList<Integer> s1 = new ArrayList<Integer>();
System.out.println(s1.equals(s));

为什么打印 true

ArrayList

doc for the equals()方法

Returns true if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal.

由于没有元素,所有条件都满足,因此 true

如果您将元素添加到两个列表中(每个列表中至少有一个),以查看所需的输出。

List.equals 的契约是,如果两个列表的所有元素都相等(根据 equals()),则两个列表相等。在这里,两者都是空列表,因此它们是相等的。通用类型无关紧要,因为无论如何都没有要比较的列表元素。

但是,它们在 == 方面并不相等,因为它们是两个不同的对象。

有关 equals()==

之间的详细信息,请参阅 this question

这是 AbstractList 中 equals 方法的 ArrayList 实现 加上一些评论它实际上做了什么:

public boolean equals(Object o) {
   if (o == this) // Not the same list so no return
       return true;
   if (!(o instanceof List)) // is an instance of List, so no return 
       return false;

   ListIterator<E> e1 = listIterator();
   ListIterator<?> e2 = ((List<?>) o).listIterator();
   while (e1.hasNext() && e2.hasNext()) { // Both have no next, so no loop    here
        E o1 = e1.next();
        Object o2 = e2.next();
        if (!(o1==null ? o2==null : o1.equals(o2)))
            return false;
   }
   return !(e1.hasNext() || e2.hasNext()); // Both validate to false, so negating false return true in the end.
} 

正如前面的答案所指出的,等于 returns 为真,因为两个对象都是 List 的实例并且具有相同的大小 (0)。

还值得一提的是,一个 List 包含 Integer 而另一个 String 并不影响行为,因为 type erasure 在 Java.