GWT JavaScript 不会捕获异常



当使用 GWT 框架转换小程序时,我偶然发现了这段代码,作者在循环中找出数组 imageNames 的长度,直到发生越界异常。它在小程序中有效,但在 GWT 中不起作用!GWT 编译后,浏览器循环并且不显示反应。用 JavaScriptException 替换 Exception 无济于事。

boolean error=false;
int n_img = -1;
String tmp;
String[] imageNames;
...
while (!error) {
try {
tmp = imageNames[(++n_img)];
} catch (Exception e) {
error = true;
}
}

您知道如何在GWT中捕获越界异常吗?

这是GWT的"缺点"之一 - 以性能的名义,没有添加额外的仿真来解决应该完全可以避免的错误。不过,这是最明显的例子之一。

首先,回想一下,JS,无论好坏,完全可以Array秒内为索引分配值,而它可能没有空间 - 您可以使用它通过跳过数组的末尾来创建一个稀疏数组,您甚至可以分配给负索引。

除了Array功能之外,Java 数组被实现,而不是读取表达式array[n]并重写它以在分配之前根据长度检查n(每次读取或写入需要再检查两次(,它保持原样。

而且,由于通常像这样的数组操作是在循环中(例如在您的代码中(,因此此更改将使循环中的每个步骤都更快,因为将边界检查作为循环条件的一部分进行是微不足道的。

而且,通常Java用户不会定期编写数组代码,而是依靠ArrayList或类似的东西 - 这确实会执行这些检查(尽管可以禁用或减少它们以提高运行时性能(。

还有一个原因:有时你想用Java编写,并期望(并非不合理地(你实际上是在处理JS输出。这允许这样的技巧:

array[array.length] = item;

以增加每个项目的数组。显然在JVM中会失败,但这是用JS编写的自然代码。

最后,除非我大错特错,否则这甚至不是一种非常优化的编写循环的方法,即使抛出和捕获该异常比仅执行<检查循环的每一步更便宜 - 我们仍在检查每一步!error是否为真!相反,只需让循环永远运行,并实际退出它,而不是要求额外的布尔值来跟踪异常已经为您跟踪的内容:

// just like the code in the question, do not do this, 
// this is just an example of how to get "too clever"
try {
while (true) {
tmp = imageNames[(++n_img)];
}
catch (Exception ignore) {
// do nothing, something "exceptional" but totally expected has occurred 
}

因此,感谢您的评论和解释性答案。它将帮助我进一步发展。我现在以这种方式更改了错误的循环

while (!error) {
try {
tmp = this.imageNames[(++n_img)];
error=(n_img==imageNames.length); // correct severe bug
} catch (Exception e) {
error = true;
}
}

最新更新