捕获Java错误

时间:2012-06-13 14:39:40

标签: java error-handling

我听说抓住java.lang.Error被认为是不好的做法。 我目前正在加载一个不保证在PATH上的.dll,并希望切换到用户配置的位置,如果不是。

try {
    System.loadLibrary("HelloWorld");
} catch(UnsatisfiedLinkError ule){
    System.load("C:/libraries/HelloWorld.dll");
}

有更好的方法吗?或者正在接受这里可以接受的UnsatisfiedLinkError

4 个答案:

答案 0 :(得分:31)

除了提供有关如何在技术上克服问题的建议外,我想花点时间解释为什么它首先被认为是“不良做法”。

让我们首先澄清Error类是什么。


在java中,抛出错误和异常(它们是主要类型)。使用throw关键字即可完成上述任一操作。每个扩展基本java.lang.Throwable的类都可以抛出。

有两个类继承自基本Throwable类:ExceptionError。这两者之间的区别在他们的文件中有解释:

  

错误 Throwable 的子类,表示严重   合理的应用程序不应该试图抓住的问题。最   这种错误是异常情况。 [...]

Source

  

Exception 及其子类是 Throwable 的一种形式   表示合理的应用程序可能需要的条件   赶上。

Source


如上所述,错误和异常因其起源不同而分开。 Error通常表示存在问题,应用程序无法从恢复。因此,不应该抓住它们。

对于RuntimeException也是如此,但它用于表示高级别层(例如方法)的问题。而Error表示低级问题(例如运行时)。


所以,既然你明白你只能捕捉你能够从中恢复的异常和错误,那么你的问题的答案应该是明确的。

是的,抓住UnsatisfiedLinkError是完全合理的,因为您的应用程序可以从中恢复。


我在article on my Blog中介绍了上述内容(更详细和示例)以及一些扩展信息。

答案 1 :(得分:2)

您应该只在特定情况下捕获错误。如果您已经探索了所有其他可能性,那么只会发现错误。我完全同意Lukas Knuth所说的一切。但我有一个小的补充。 如果您发现任何类型的错误,请确保从尽可能窄的范围捕获错误。此外,如果可能,请确保将捕获错误的方法声明为final。原因是捕获错误通常会导致一些非常不稳定的程序。考虑到你在稍后扩展为调用其他方法的方法上捕获错误,所有这些基础方法现在也会被覆盖的catch捕获(无意中)错误。

如果您需要捕捉错误,请在狭窄,受控制的情况下进行。

答案 2 :(得分:0)

loadLibrary调用findLibrary()会有所帮助,但它受到保护,最好的办法就是编写自己的类扩展ClassLoader。类加载器有一个名为findLibrary()的受保护方法,它将返回一个库的路径,如果它不存在则返回null。这样你就可以检查null而不是捕获错误。我不确定这实际上是否“更好”,但它会消除你对try catch的需求;

答案 3 :(得分:0)

如果您正在进行防御性编码并且可以从某个问题中恢复,那么它就不是Java Error。如果不太可能出现这样的问题,那么创建一个Exception的子类并抛出并捕获它。如果可能出现这样的问题,那么它甚至不应该抛出Exception;但是,应该是常规代码流的一部分。

try {
  if (config.hasCustomDLL()) {
    System.load(config.getCustomDLL());
  } else {
    System.loadLibrary(Config.DEFAULT_DLL);
  }
} catch (UnstatisfiedLinkError e) {
  System.out.println("Error loading DLL: " + e);
}

Errors用于真正糟糕的故障,而不是可恢复的“故障”,如果有合适的解决方法,它甚至都不会失败。不要使设计用于处理故障的系统过载,而是能够以多种方式配置系统。