2011-10-25 50 views

回答

9

另一種方法是避免使用instanceof和設計你的類(在OO感)。

由於instanceof運算符具有相應的「instanceof」字節碼指令,因此可能不會有更高性能的方法;但這也可能取決於實際的JVM如何優化。

+5

這是一個比答案更多的評論。這個問題基本上是,「爲了做X(我沒有說明X),我必須做Y; Y有多快,並且有沒有其他選擇?」你建議根本不要做X,這不能解決OP的問題。 –

+1

@MichaelMcGowan:根據我的經驗,'instanceof'通常與糟糕的設計有關。對我而言,不使用它是最好的選擇。如果你不使用它,你不需要關心它的性能。 – jeha

+0

我完全同意它經常與不良設計有關。但是,這並不意味着情況總是如此,有時由於各種原因,人們會遇到不好的設計。 –

2

如果你想檢查對象是某一類的一個實例(但如果它extendsimplements吧),可能與==比較班會更快:

o.getClass() == YourClass.class 

否則自instanceof關鍵字已爲這一特定目的而創建的,我不看你怎麼可以永遠做的更好..

+1

我不認爲這樣更快,因爲'ref instanceof class'直接映射到'instanceof'字節碼操作。你的方法增加了方法調用'getClass'。 –

+0

嘗試檢查對象是否屬於某個子類時,您嘗試使用'getClass'進行的比較將不起作用。例如,如果你有'FileReader'擴展'InputStreamReader'繼而擴展/實現'Reader',那麼在一個用'FileReader'實例化的對象上調用'getClass'永遠不會產生除FileReader類之外的任何東西,所以' o.getClass()== Reader或or.getClass()== InputStreamReader'都將計算爲'false'。另一方面,'instanceof'在所有三類案例中都會產生「真」。 – amn

2

我想你實際上異形你的代碼,並發現您的instanceof使用是一個不平凡的業績衝擊嗎?如果沒有,你幾乎肯定會解決一個不值得花時間去解決的問題。

如果你正在做的是這樣的代碼:

if (something instanceof MyClass) { 
    MyClass mySomething = (MyClass) something; 
    //... 
} else { 
    //exceptional case 
} 

那麼有可能先嚐試中投,並允許ClassCastException是你的「特殊情況」:

try { 
    MyClass mySomething = (MyClass) something; 
} catch (ClassCastException cce) { 
    //exceptional case 
} 

現在,雖然它可能是不成熟的優化,但重新考慮您的設計還爲時尚早。過度使用instanceof是一種設計氣味。一般來說,你應該使用泛型和多態來減少使用instanceof(實際上是鑄造)到(接近)零的次數。

  1. 如果不同的代碼應該根據對象的類型來運行,考慮使該代碼的對象的實例的方法和具有不同類型的符合一個接口。

  2. 如果你發現自己「知道」的對象是某一類型,但你已經做了一些步驟,使該事實編譯器失去跟蹤(例如,你把它變成一個原始List),它可能是一個候選人的generification。

7

instanceof是相當該死的快。但是,這通常是設計思路不清的症狀。

它會和(成功)演員具有相同的表現,因爲它們的表現完全相同。的確,這個任務大致相當於一個「虛擬」方法調用。

理智的實現:對於類,它只是獲取運行時類並查看固定偏移量以檢查超類的問題(只要您沒有對HotSpot超過八個類的繼承鏈) 。接口有點棘手,但通常對於任何特定的運行時類緩存了最後兩個用例。所以這也很快。