是否可以使用exception来检查数组边界?

我想检查给定的坐标是否与数组有关。

public boolean checkBounds(int x, int y) { try { Object val = array[x][y]; return true; } catch (ArrayIndexOutOfBoundsException e) { return false; } } 

我能这样做吗? 这是一种有效的方法吗?

当我们使用exception来执行边界检查时会发生什么?

使用exception来处理诸如空检查,边界检查,文件存在检查等操作时,每当抛出exception时都会引入大量开销。

如果您只是检查边界,您会做什么:

  • 检查一个数组的大小对0和对
  • 返回结果

使用基于exception的检查时您实际在做什么:

  • 检查数组的边界
  • 启动javaexception机制(带有所有开销)
  • 创建一个新的Exception对象
  • 转储整个堆栈跟踪
  • 用所有堆栈数据填充新创建的对象
  • 抓住例外
  • 返回结果

性能比较

通过这个简单的测试程序,我测量了两种类型的arrays边界检查的速度。

 public class BoundsCheckTest { final static int[] array = new int[1]; final static Random gen = new Random(); public static void main(String[] args){ boolean ret = false; int tries = 100000000; long timestart = System.nanoTime(); for (int a=0; a< tries; a++) { ret = method1(); } long timeend1 = System.nanoTime(); System.out.println(); for (int a=0; a< tries; a++) { ret = metod2(); } long timeend2 = System.nanoTime(); System.out.println(); long t1 = timeend1-timestart; long t2 = timeend2-timeend1; System.out.println("\ntime 1=["+t1+"]\n 2=["+t2+"]"+ "\ndiff=["+Math.abs(t1-t2)+"] percent diff=["+(100d*t2/t1-100)+"]"); } private static boolean metod2() { try { int val = array[gen.nextInt(2)]; return true; } catch (Exception e) { return false; } } private static boolean method1() { return array.length < gen.nextInt(2); } } 

结果:

JDK 7,eclipse Run as模式:

 time check=[911620628] exc=[1192569638] diff=[280949010] percent diff=[30.818632375220886] 

JDK 7,eclipse Debug模式:

 time check=[931243924] exc=[651480777121] diff=[650549533197] percent diff=[69858.12378809143] 

禁用调试时的速度损失并不是很显着,尽管它是可见的:没有例外的代码大约快30%(大约50%的错误返回)。 调试模式下的速度损失是惊人的。 基于exception的代码运行速度比正常的直接数组大小检查慢约700倍。

例外哲学

exception背后的一般思想是允许一种处理exception条件的方法。 在这种情况下,根本没有exception条件 - 范围检查只是代码的正常部分。 仅仅因为这个原因,不应该在这种情况下使用例外。