簡體   English   中英

哪個更好,更便宜:類匹配與異常?

[英]Which is preferable and less expensive: class matching vs exception?

哪個更便宜,更可取:put1還是put2?

Map<String, Animal> map = new Map<String, Animal>();

void put1(){
 for (.....)
  if (Animal.class.isAssignableFrom(item[i].getClass())
   map.put(key[i], item[i]);

void put2(){
 for (.....)
  try{
   map.put(key[i], item[i]);}
  catch (...){}

問題修訂 :問題不是那么清楚。 讓我稍微修改一下這個問題。 我忘記了轉換,因此put2依賴於強制轉換異常失敗。 isAssignableFrom(),isInstanceOf()和instanceof在功能上相似,因此產生相同的費用,只有一個是包含子類的方法,而第二個是精確類型匹配,第三個是運算符版本。 反射方法和例外都是昂貴的操作。

我的問題是那些在這個領域做過一些基准測試的人 - 哪個更便宜,也更可取:instanceof / isassignable from vs cast exception?

void put1(){
 for (.....)
  if (Animal.class.isAssignableFrom(item[i].getClass())
   map.put(key[i], (Animal)item[i]);

void put2(){
 for (.....)
  try{
   map.put(key[i], (Animal)item[i]);}
  catch (...){}

可能你想要:

if (item[i] instanceof Animal)
    map.put(key[i], (Animal) item[i]);

這幾乎肯定比調用isAssignableFrom

或者在C#中(因為你添加了c#標簽):

var a = item[i] as Animal;
if (a != null)
    map[key[i]] = a;

編輯 :更新的問題是更好的:instanceof或cast-and-catch。 功能基本相同。 性能差異可能不大,我不得不衡量它; 一般拋出異常很慢,但我不知道其余的。 所以我會根據風格來決定。 說出你的意思。

如果你總是期望期望item[i]成為一個Animal ,你只是要特別小心,投射和捕獲。 否則我發現使用instanceof更清楚,因為它明確地說出你的意思:“如果這個對象是動物,就把它放在地圖中”。

我糊塗了。 如果item[i]不是Animal ,那么map.put(key[i], item[i])編譯?

也就是說,第一種方法說明了你打算做什么,雖然我相信instanceof會是一個更好的檢查。

通常情況下,異常處理會明顯變慢,因為它應該被用於特殊事物(很少發生),因此VM制造商不會花費太多工作來加速它。

您的代碼的tr / catch版本我會認為是濫用異常處理,並且永遠不會考慮這樣做。 你想要做這樣的事情的事實可能意味着你的設計很差,項目應該是Animal []而不是其他東西,在這種情況下你根本不需要在運行時檢查。 讓編譯器為您完成工作。

我同意之前的回答 - 這不會編譯。

但是,在我看來,無論是異常還是檢查取決於功能的目的。

item [i]不是動物錯誤/例外情況嗎? 預計很少發生嗎? 在這種情況下,它應該是一個例外。

如果它是邏輯的一部分 - 意味着你期望item [i]是很多東西 - 並且只有當你想要放入地圖時它才是動物。 在這種情況下,檢查實例是正確的方法。

更新:我還將添加一個示例(位跛):

哪個更好:(1)

if ( aNumber < 100 ) {   
 processNumber(aNumber); 
}

或(2)

try {
    processNumber(aNumber); //Throws exception if aNumber >= 100
} catch () {
}

這取決於程序的功能。 (1)可用於計算任何整數輸入的數字<100。 如果processNumber期望百分比值不能大於100,則將使用(2)。

不同的是,程序(2)獲得aNumber> 100是錯誤的。但是,對於程序(1),aNumber> 100是有效的,但只有當aNumber <100時才會發生“某事”。

PS - 這可能對你沒有任何幫助,如果是這種情況我會道歉。

你的兩個選擇並不是真的相同。 選擇哪一個,完全取決於您的代碼應該做什么:

  • 如果該項目應該始終是一個Animal ,那么你應該使用put2 (如果不是這樣的話,它會拋出...)
  • 如果該項可能是也可能不是Animal ,則應使用put1 (檢查條件,而不是錯誤......)

如果您正在編寫代碼,那么從不關心性能!

暫無
暫無

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

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