簡體   English   中英

Java反射檢查傳遞的對象是否是相同類型

[英]Java reflection check if passed Objects are same type

我有一個帶有compare方法的類。 該方法以兩個對象作為參數。 使用java反射,我可以獲取所有私有和受保護的字段,並使用一些奇特的東西檢查它們的返回類型,然后對它們進行處理。

這對我個人很有好處。 我知道我想做什么,所以我只比較兩個相同類型的對象即可。

但是...這被很多人使用...並且有時他們無法閱讀Javadoc和注釋以及我放置的其他內容,因此我必須檢查它們是否傳遞相同類型的對象。 例如,您有:汽車a,汽車b,卡車a,卡車b ...等。.我需要檢查兩個傳遞的參數是否實際上是同一類型以進行比較(汽車與汽車,卡車與卡車.. )

所以...我不知道這些東西。我應該使用反射來列出所有字段的大小,然后檢查所有字段的名稱是否相同? 還是有更好的解決方案? 因為編寫了諸如fieldsOfA.size與fieldOfB.size ...之類的內容,然后進行循環,如果它們相同,則檢查名稱看起來有點奇怪。

還有另一個問題。 這些對象具有其他一些對象的列表-例如,“汽車”具有“車輪”列表。並且您正在將車輪與其他汽車進行比較。 他們在列表中有Wheel 1,Wheel 2,Wheel 3,Wheel 4。.,第二輛汽車有Wheel1,Wheel 2,WHeel 4和WHeel 3 ..

因此,對象是相同的,但是只是位置已切換。是否有防止這種情況的方法? 我有一個跟蹤代碼,用於存儲這些對象中的每個差異。因此,如果它們的位置不同,則會給我帶來兩個變化。。車輪3與其他汽車不同,車輪4與其他汽車不同。

但是它們仍然是相同的...我不知道如何通過反思來解決...任何想法?

要比較類,只需使用if(object1.getClass() == object2.getClass())

公平地說,它是a.getClass().isInstance(b)a.getClass().isAssignableFrom(b)但我總是忘記哪個是哪個。

boolean isInstance(Object obj)
Determines if the specified Object is assignment-compatible with the object represented by this Class.

boolean isAssignableFrom(Class<?> cls)
Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter.

您可能需要第一個。

您可以使用instanceof運算符。

例如:

public boolean isCar(Vehicle x) {
    if (x instanceOf Car) {
        return true;
    } else {
        return false;
    }

    // note: you can also just do "return x instanceof Car"
}

聽起來您正在嘗試編寫通用等於方法。 以防萬一:在一般情況下,這會失敗,因為對象相等不一定意味着所有字段都相等,甚至所有公共字段都相等。 即使某些字段不同,兩個Java對象也可能故意相等。 給定類的兩個實例之間的相等性由程序員設計該類來定義,並且對其子類進行隱式繼承的任何人都必須遵守其相等性契約。

鑒於此,嘗試挖掘對象的超類的私有字段通常不是一個好主意。 一個更好的主意: super.equals()

因此,假設您編寫了一個擴展Vehicle的類Truck,而Truck定義了兩個私有字段maxLoadhasTrailerHitch 您定義兩個卡車是否相等; 假設您需要這兩個字段相等。 實際上,您可能還希望它們滿足Vehicle定義的相等條件。 所以,你的equals可能是這個樣子:

@Override
public boolean equals(Object obj) {
    // check for type
    if (!(obj instanceof Truck)) return false;
    // check private fields
    Truck other = (Truck)obj;
    if (this.maxLoad != other.maxLoad ||
        this.hasTrailerHitch != other.hasTrailerHitch) return false;
    // check for Vehicle equality
    if (!super.equals(obj)) return false;
    // everything checks out!
    return true;
}

為了顯示的目的,我寫的內容比實際編寫的要緊湊。 理想情況下,檢查的順序無關緊要; 我將超類檢查放到最后,因為我知道兩個私有字段的比較運行得非常快,但是我不一定知道檢查Vehicles涉及什么。

注意instanceof是如何工作的。 如果某人(包括您!)稍后編寫了Truck的子類,則instanceof將為true,因此,如果他們執行與您相同的操作並調用super.equals(obj) ,則Truck.equals將檢查這兩個私有字段,正如它應該。 如果您不是嚴格的檢查instanceof ,而是更嚴格的話,請說:

if (obj.getClass().getName().equals("my.pkg.Truck")) // ...

那么Truck的子類將無法正確檢查這些私有字段。 例如, DumpTruck兩個實例永遠不會相等-可能不是您想要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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