问题:Java中的异常处理实际上是否很慢?
传统观念以及许多谷歌搜索结果表明,不应将特殊逻辑用于Java中的正常程序流程.通常有两个原因,
和
这个问题是关于#1.
例如,这个页面将Java异常处理描述为"非常慢",并将缓慢与异常消息字符串的创建联系起来 - "然后将此字符串用于创建抛出的异常对象.这并不快." Java中的有效异常处理这篇文章说"其原因在于异常处理的对象创建方面,从而使异常本身变得缓慢".另一个原因是堆栈跟踪生成减慢了它的速度.
我的测试(使用Java 1.6.0_07,Java HotSpot 10.0,在32位Linux上)表明异常处理并不比常规代码慢.我尝试在循环中运行一个执行一些代码的方法.在方法结束时,我使用布尔值来指示是返回还是抛出.这样实际处理是一样的.我尝试以不同的顺序运行方法并平均我的测试时间,认为它可能是JVM升温.在我的所有测试中,投掷至少与返回一样快,如果不是更快(最多快3.1%).我对我的测试错误的可能性持开放态度,但我没有看到代码示例,测试比较或过去一两年中显示Java中的异常处理的结果慢.
让我沿着这条路走下去的是我需要使用的API,它将异常作为正常控制逻辑的一部分.我想在他们的使用中纠正它们,但现在我可能无法做到.相反,我是否必须赞美他们的前瞻性思维?
在即时编译中的高效Java异常处理文章中,作者建议单独存在异常处理程序,即使没有抛出异常,也足以阻止JIT编译器正确优化代码,从而减慢它的速度.我还没有测试过这个理论.
让堆栈跟踪远离它,让我们说"错误"的概念是你不想发生的问题,但确实如此.
如果我使用布尔系统来检查操作是否成功完成,它将看起来像这样:
String[] array = new String[10];
int i = 0;
public boolean accessValue(int id) {
if(id < array.length) {
//do something
return true;
}
return false;
}
while(true) {
if(!accessValue(i++)) {
//tend to situation
}
}
Run Code Online (Sandbox Code Playgroud)
如果我使用Exceptions,它将如下所示:
class InvalidAccessException extends Throwable {
}
public boolean accessValue(int id) throws InvalidAccessException {
if(!id < array.length || !id >= 0)
throw new InvalidAccessException();
//do something
}
while(true) {
try {
accessValue(i++);
}catch(InvalidAccessException e) {
//tend to situation
}
}
Run Code Online (Sandbox Code Playgroud)
对我来说唯一重要的是,当问题发生时,我会以某种方式得到通知,我会有办法处理这种情况.哪种方式更实践?它只是取决于具体情况,还是有理由选择一个而不是另一个?
我的程序正在处理一些JSON数据.我希望程序在一段时间内保持稳定,JSON数据可以随着源的更新和改进而改变.这是从数据中返回一些图像文件名的当前函数:
@Override
public String createImgName() {
try {
// data["image"]["full"]
return getJSONData().getJSONObject("image").getString("full");
}
catch(JSONException e) {
try {
// data["id"] + ".png"
return getJSONData().getJSONObject("id")+".png";
}
catch(JSONException e2) {
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
还有一些我try可以获得图像名称的东西.但该计划将变得非常丑陋.
在try成功之前是否存在多种事物的语法?在我的情况下,该return声明打破了成功的程序,但可能并非总是如此.