[英]Java: Objects in collections
Vector v = new Vector();
String a = "element";
String b = "element";
v.add(a);
v.contains(b) // true
所以我的問題是:如果vector
中元素的類型是Object
不是contains
,則將equals()
未覆蓋為Object
,將Object
與內部的String
進行比較,我想知道表面下發生了什么。
看這里 :
如果此向量包含指定的元素,則返回
true
。 更正式地,返回true
當且僅當該載體含有至少一種元素e
使得(o==null ? e==null : o.equals(e))
該.equals
被稱為是最終是重寫.equals
。 方法參數使用Object
鍵入的事實並不意味着向量將使用Object
類的.equals
方法。 如果存在的話,它將使用覆蓋的.equals
方法(否則使用從Object
繼承的方法)。 鍵入Object
的參數僅表示您可以傳入任何Object
( Object
是String
,因為所有Java類都繼承自Object
)。
您的困惑源於這樣的事實,即在運行時調用的方法取決於要調用其方法的對象的實際類型 。 有關更多信息,請參見關於方法調用的運行時評估的JLS部分。 您可以看到它提到了“目標引用”,這是您要調用其方法的對象。
考慮否則會發生什么:行為會根據method參數的類型而不是實例的類型而改變。 這將完全擊敗多態性! 考慮經常使用的Animal
示例:假設有一個名為makeNoise()
方法返回字符串"Noise!"
。 現在,您有兩個子類Dog
和Cat
,它們重寫了返回"Woof!"
的方法"Woof!"
和"Meow!"
分別。 現在讓我們說您有這種方法:
public void animalNoiseMaker(Animal animal) {
System.out.println(animal.makeNoise());
}
按照您的期望,無論您傳遞的是Dog
還是Cat
實例,它每次makeNoise
在Animal
上調用makeNoise
並打印Noise!
因為參數類型是Animal
。 這不是非常有用的行為。
Vector
的contains
方法調用indexOf
,該方法將Vector
的元素與我們使用equals
搜索的元素進行比較。
如果在運行時類型為String
的實例上執行equals
(在您的代碼中就是這種情況),則執行String
的equals
(這是方法的重載),並且如果傳遞的參數也是String
且在String
包含相同的字符同樣的順序,它將返回true。
這是“表面之下”的情況:
public boolean contains(Object o) {
return indexOf(o, 0) >= 0;
}
public synchronized int indexOf(Object o, int index) {
if (o == null) {
for (int i = index ; i < elementCount ; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = index ; i < elementCount ; i++)
if (o.equals(elementData[i])) // if the runtime type of o is String,
// String's equals is executed
return i;
}
return -1;
}
對象已經包含equals方法的定義。 因此,如果您要調用的對象包含(在本例中為b)不屬於equals方法的類,則它將使用Object的equals定義。
Object中equals的定義比較兩個對象的地址,如果相等則返回true。 從https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object) :
類Object的equals方法在對象上實現了最有區別的對等關系。 也就是說,對於任何非空參考值x和y,當且僅當x和y引用同一個對象(x == y的值為true)時,此方法才返回true。
如果類重寫equals方法(對於String就是這種情況),那么將使用重寫版本。
您正在使用通常稱為“原始類型”的集合。 您可以向其中添加任何內容,但在運行時可能會導致問題(類型轉換)。 看到這里進行討論
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.