2011-05-27 82 views
34

我想比較Java中的類類型。在Java中比較類類型

我想我能做到這一點:

class MyObject_1 {} 
class MyObject_2 extends MyObject_1 {} 

public boolean function(MyObject_1 obj) { 
    if(obj.getClass() == MyObject_2.class) System.out.println("true"); 
} 

我想在情況比較,如果傳遞給函數的OBJ從MyObject_1或不延長。 但這不起作用。看起來像getClass()方法和.class提供了不同類型的信息。

如何比較兩個類的類型,而不必創建另一個虛擬對象來比較類的類型?

+0

這個問題令人困惑,並且在比較類/接口的情況下,我誤導了「==」的工作方式。這個例子應該是獨立的。在這個例子中,你傳遞給你的函數應該是這樣的! – croraf 2017-01-02 13:35:23

回答

40

試試這個:

MyObject obj = new MyObject(); 
if(obj instanceof MyObject){System.out.println("true");} //true 

因爲繼承的,這是有效的接口,太:

class Animal {} 
class Dog extends Animal {}  

Dog obj = new Dog(); 
Animal animal = new Dog(); 
if(obj instanceof Animal){System.out.println("true");} //true 
if(animal instanceof Animal){System.out.println("true");} //true 
if(animal instanceof Dog){System.out.println("true");} //true 

進一步的閱讀上的instanceof:http://mindprod.com/jgloss/instanceof.html

+0

但是如果我想檢查動物是狗的一個實例會發生什麼?它仍然有可能嗎? 說: 公共無效支票(動物的obj){ 如果(OBJ的instanceof狗){的System.out.println( 「真」);}} 這仍然是可能的嗎? – Carven 2011-05-27 08:50:17

+0

@xEnON:這是可能的,但會一直返回false。你不能檢查一個接口是否是一個具體類的實例。 – Thor 2011-05-27 08:56:52

+0

因此,如果我有使用此多態性功能的函數,我無法在運行時檢查其確切的類類型? – Carven 2011-05-27 09:00:17

9

它在我的機器上打印true。它應該,否則Java中的任何內容都不會按預期工作。 (這在JLS中有解釋:4.3.4 When Reference Types Are the Same

你有多個類加載器嗎?


啊,而且響應此評論:

我意識到我在我的 問題一個錯字。我應該是這樣的:

MyImplementedObject obj = new MyImplementedObject(); 
if(obj.getClass() == MyObjectInterface.class) System.out.println("true"); 

MyImplementedObject實現 MyObjectInterface因此,換句話說,我 正與它的實現 對象比較它。

OK,如果你想查詢你可以做兩種:

if(MyObjectInterface.class.isAssignableFrom(obj.getClass())) 

或更簡潔

if(obj instanceof MyobjectInterface) 
+0

我知道我的問題有一個錯字。我應該是這樣的: MyImplementedObject obj = new MyImplementedObject(); (obj.getClass()== MyObjectInterface .class)System.out.println(「true」);如果(obj.getClass()== MyObjectInterface .class) MyImplementedObject實現MyObjectInterface 換句話說,我將它與它的實現對象進行比較。 – Carven 2011-05-27 08:33:47

+0

我用我的意思是正確的代碼更新了我的帖子。對困惑感到抱歉。 – Carven 2011-05-27 08:40:41

+0

@xEnOn和我已更新我的:-) – 2011-05-27 08:42:02

24

如果你不想或者不能使用instanceof,然後用equals比較:

if(obj.getClass().equals(MyObject.class)) System.out.println("true"); 

順便說一句 - 這很奇怪,因爲聲明中的兩個Class實例應該是相同的,至少在您的示例代碼中。他們可以是不同的,如果:

  • 類具有相同的短名稱,但在不同的包中定義
  • 類具有相同的全名,但由不同的類加載器加載。
3

如前所述,除非您在兩個不同的類加載器上加載了相同的類,否則您的代碼將工作。 如果你需要同一時間在內存中同一個類的多個版本,或者你正在做一些奇怪的事情(就像我一樣),這可能會發生。

在這種情況下,如果您想將它們視爲同一類(根據具體情況而定,這可能是合理的),您可以匹配它們的名稱進行比較。

public static boolean areClassesQuiteTheSame(Class<?> c1, Class<?> c2) { 
    // TODO handle nulls maybe? 
    return c1.getCanonicalName().equals(c2.getCanonicalName()); 
} 

請記住,這種比較只會做它的工作:比較類名;我認爲你不能從一個版本的類到另一個版本,並且在考慮反思之前,你可能想確保你的類加載器有一個很好的理由。

1

檢查Class.java來源的equals())代碼

public boolean equals(Object obj) { 
return (this == obj); 
} 
0

嗯......請記住,類可能會或可能不會實現equals( - 這是不規範所要求。例如,HP Fortify將標記myClass.equals(myOtherClass)。