Java 使用异常检查数组边界可以吗?
我想检查给定的坐标是否使用数组Java 使用异常检查数组边界可以吗?,java,exception,indexoutofboundsexception,range-checking,Java,Exception,Indexoutofboundsexception,Range Checking,我想检查给定的坐标是否使用数组 public boolean checkBounds(int x, int y) { try { Object val = array[x][y]; return true; } catch (ArrayIndexOutOfBoundsException e) { return false; } } 我能那样做吗?这是一种有效的方法吗?当我们使用异常执行边界检查时会发生什么? 使用异常来处理
public boolean checkBounds(int x, int y) {
try {
Object val = array[x][y];
return true;
} catch (ArrayIndexOutOfBoundsException e) {
return false;
}
}
我能那样做吗?这是一种有效的方法吗?当我们使用异常执行边界检查时会发生什么?
使用异常来处理空检查、边界检查、文件存在性检查等操作会在抛出异常时带来大量开销
如果只检查边界,您会做什么:
- 根据0和
- 返回结果
- 检查数组的边界
- 启动java异常机制(及其所有开销)
- 创建一个新的异常对象
- 转储整个堆栈跟踪
- 用所有堆栈数据填充新创建的对象
- 抓住例外
- 返回结果
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,eclipseDebug
模式:
time check=[911620628]
exc=[1192569638]
diff=[280949010] percent diff=[30.818632375220886]
time check=[931243924]
exc=[651480777121]
diff=[650549533197] percent diff=[69858.12378809143]
禁用调试时的速度损失不是很明显,尽管它是可见的:没有异常的代码大约快30%(大约有50%的错误返回)。调试模式下的速度损失是惊人的。基于异常的代码的运行速度比正常的直接向上数组大小检查慢700倍左右
例外哲学
异常背后的一般思想是允许一种处理异常情况的方法。在这种情况下,根本没有例外情况-范围检查只是代码的正常部分。仅出于这个原因,在这种情况下不应使用异常。这让我想起了“有效Java”中的第57项:仅在异常情况下使用异常。有一个很像你的;-)在对这个问题投反对票之前,请注意这是一个自我回答的问题。“基于异常的代码的运行速度比正常的直接向上数组大小检查快约700倍”此时您为什么要颠倒您的陈述?基于异常的代码仍然比较慢。对于一个用例,如果异常在一百万次访问中发生一次呢?编辑:测试(非常罕见的异常场景,如1:500.000)=>try-catch比边界检查快得多,一旦JIT启动,差异就不再那么大了