繁体   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