簡體   English   中英

Java:集合中的對象

[英]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的參數僅表示您可以傳入任何ObjectObjectString ,因為所有Java類都繼承自Object )。

您的困惑源於這樣的事實,即在運行時調用的方法取決於要調用其方法的對象的實際類型 有關更多信息,請參見關於方法調用的運行時評估的JLS部分。 您可以看到它提到了“目標引用”,這是您要調用其方法的對象。

考慮否則會發生什么:行為會根據method參數的類型而不是實例的類型而改變。 這將完全擊敗多態性! 考慮經常使用的Animal示例:假設有一個名為makeNoise()方法返回字符串"Noise!" 現在,您有兩個子類DogCat ,它們重寫了返回"Woof!"的方法"Woof!" "Meow!" 分別。 現在讓我們說您有這種方法:

public void animalNoiseMaker(Animal animal) {
    System.out.println(animal.makeNoise());
}

按照您的期望,無論您傳遞的是Dog還是Cat實例,它每次makeNoiseAnimal上調用makeNoise並打印Noise! 因為參數類型是Animal 這不是非常有用的行為。

Vectorcontains方法調用indexOf ,該方法將Vector的元素與我們使用equals搜索的元素進行比較。

如果在運行時類型為String的實例上執行equals (在您的代碼中就是這種情況),則執行Stringequals (這是方法的重載),並且如果傳遞的參數也是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM