2010-04-17 43 views
1

讓我們假設我們有一個方法接受Object類型的兩個參數o1和o2並返回一個布爾值。我想這個方法只有當參數是同一類的實例,如返回true:我怎樣才能找出兩個參數是否是相同的,但未知的類的實例?

foo(new Integer(4),new Integer(5)); 

應該返回true,但是:

foo(new SomeClass(), new SubtypeSomeClass()); 

應該返回false,也:

foo(new Integer(3),"zoo"); 

應該返回false。

我相信一個方法是比較完整的類名:

public boolean foo(Object o1, Object o2){ 
Class<? extends Object> c1 = o1.getClass(); 
Class<? extends Object> c2 = o2.getClass(); 
if(c1.getName().equals(c2.getName()){ return true;} 
return false; 
} 

另一種條件語句應該是:

if (c1.isAssignableFrom(c2) && c2.isAssignableFrom(c1)){ return true; } 

後者的選擇是相當緩慢的。這個問題還有其他的選擇嗎?

回答

10

不要完全合格的類名麻煩 - 只是比較類引用:

public boolean foo(Object o1, Object o2) { 
    return o1.getClass() == o2.getClass(); 
} 

類是按名稱和類加載器基本上是獨特的 - 因此,如果對象是同一類這將返回false名字,但由不同的類加載器加載,但這可能是合適的:它們可以是完全不同的類,除了名字!但是,如果類具有相同的名稱和類加載器,則它們將具有相同的引用。

請注意,如果o1o2爲空,則會拋出NullPointerException,但這又可能是您想要的。

+0

謝謝你回答我的問題喬恩... – Ingmar 2010-04-17 15:12:11

0

你可以限定比較慢嗎?比較什麼?還請詳細說明您的使用場景?在java中,Object api包含一個equals/hashCode方法,用於識別對象之間的相等性。它看起來好像這是你可能試圖找到,即:

new Integer(4).equals(new Integer(5)) 

在這種情況下,首要的最佳執行等於在SomeClass的如下:

public boolean equals(Object obj) { 
    if (obj instanceof SomeClass) { 
     return ((SomeClass) obj).identityField.equals(identityField); 
    } 
    return false; 
} 
public int hashCode() { 
    return 31 * identity.hashCode(); 
} 

確保您提供你的對象內的身份。

相關問題