java - 检测 Java 异常的责任变量

标签 java exception fault

我有一组 Java 程序遇到一些运行时异常。我想知道是否有一种自动机制来识别导致异常的罪魁祸首变量。

例如:

public int multiply(String x, String y){
    return Integer.parseInt(x) * Integer.parseInt(y);
}

当你调用multiply("4","ab")时,在运行时,我们会得到一个NumberFormatException。是否有任何自动化过程来识别变量 y 导致/负责此异常?

编辑1:

在收到优秀开发人员的一些建议后,我认为它无法在代码级别解决,而我应该在Java编译器中做一些事情。在这种情况下,是否有人考虑过更改 Java 编译器可能会有所帮助?

即使在编译器中不可能,任何人都可以对 JVM 中的更改提出建议吗?

最佳答案

更新:

I am thinking that it cannot be solved at the code level, rather I should do something in the Java compiler.

根据定义,编译器无法检测到 RuntimeException,它们只能在程序执行时捕获和处理。这只能在“代码级别”解决。

Even if it is not possible in the compiler, can anyone give suggestion about the changes in JVM?

尽管我尽了最大努力,您还是坚持走这条路,所以我将尽力解释您必须做什么。但请注意,a)这非常复杂,b)几乎肯定不是正确的解决方案。 修复您的代码,而不是 JVM

您基本上需要重新设计 Java bytecode包含您需要的其他上下文,然后更改和 compile the JDK from source 。这在理论上是可能的,因为 Java 是开源的,但这将是一项艰巨的任务。没有“给我更多信息”标志可以直接传递给 JVM;这是 JVM Options 的列表.

<小时/>

真正的答案从这里开始:

这取决于您所说的“自动化”是什么意思。据我所知,没有办法检查异常来确定哪个变量导致了错误(我希望这对于 NPE 来说是正确的,这会非常有帮助)。但您可以改进代码以使这一点更加清晰。

使用调试器单步执行程序

在我们进入自动化之前,一个选择是 use the Java debugger逐行查看代码并准确查看失败发生的位置。这是一个高度手动的过程,但可以帮助您查找难以理解的故障。

将异常调用分成单独的行

堆栈跟踪确实提供了关联的行号,因此如果您将方法更改为:

public int multiply(String x, String y){
  int intX = Integer.parseInt(x);
  int intY = Integer.parseInt(y);
  return intX * intY;
}

然后 NumberFormatException 现在将出现在该函数的第一行或第二行,让您查看哪一行导致了错误。

引发具有更多上下文的包装器异常

行号并不是最能提供信息的,我们可以通过提出自己的异常来做得更好:

private int parseIntMsg(String num, String desc)
      throws IllegalArgumentException {
  try {
    return Integer.parseInt(num);
  } catch (NumberFormatException e) {
    throw new IllegalArgumentException(
        "Failed to parse "+desc+"; was '"+num+"'", e);
  }
}

public int multiply(String x, String y) {
  return parseIntMsg(x, "x") * parseIntMsg(y, "y");
}

现在,这将引发更清晰的 IllegalArgumentException ,并显示消息 Failed to parse x;是“ab”

在调用此方法之前进行健全性检查

这里真正发生的事情是你没有在正确的时间处理这个错误情况。相反,尽早进行健全性检查,并明确地处理它们。您正在从用户那里读取字符串?明确地检查它是否是一个数字,如果不是,则将其交还给用户进行更正,而不是等到您进入代码的核心并传递可能是也可能不是有效整数的字符串。实际上,您定义的这个 multiply(String, String) 方法不应该有用。相反,将您的输入显式解析为您想要使用的类型,然后在验证解析成功后显式使用它们。请参阅Why is it good to split a program into multiple classes?有关该主题的更多想法。

<小时/>

另请考虑使用 Preconditions来自优秀的 Guava 库;这些实用方法可让您添加大量丰富的错误消息以及对代码失败时发生的情况的期望。

关于java - 检测 Java 异常的责任变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24702064/

相关文章:

java - 发生异常后如何关闭 BufferedReader?

java - 在 Android 中,我可以在没有 Intent 的情况下在 Activity 之间移动对象吗?

java - Timer util 不会为 JLabel 添加新行

php - 有没有一种静态方法可以在 php 中抛出异常

java - 有什么方法可以不将 'instance of' 与我无法扩展的对象一起使用?

c - 段错误,增加指针中的值

c - 我不明白我是如何遇到段错误的

c - 连续调用同一数组时出现奇怪的段错误

java - 为什么 rs.Next() 跳过列

java - 在浏览器中打开远程html文件