[英]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定義了兩個私有字段maxLoad
和hasTrailerHitch
。 您定義兩個卡車是否相等; 假設您需要這兩個字段相等。 實際上,您可能還希望它們滿足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.