Hec*_*ret 23 java debugging nullpointerexception
我知道我可以使用这些技术找出Java中的变量是否为null:
(var==null)- >太多的工作try { ... } catch (NullPointerException e) { ...} - >它告诉我什么行抛出异常考虑以下代码行:
if (this.superSL.items.get(name).getSource().compareTo(VIsualShoppingList.Source_EXTRA)==0)  {
我想知道是否有一种通用的方法来以编程方式找出哪个变量(不仅仅是行)在某个代码区域中抛出NullPointerException.在这个例子中,知道这一点
Asa*_*aph 28
因为即使没有涉及变量也可能导致空指针异常:
throw new NullPointerException();
我不得不说,没有通用的方法可以将空指针异常固定到特定变量.
你最好的选择是尽可能少地在每一行上添加语句,以便明显是什么导致空指针异常.考虑在问题中重构代码,看起来像这样:
List items = this.superSL.items;
String name = items.get(name);
String source = name.getSource();
if (source.compareTo(VIsualShoppingList.Source_EXTRA) == 0)  {
    // ...
}
这是更多的代码行.但它也更具可读性和可维护性.
Von*_*onC 11
您可能会考虑,正如这里所宣布的,JDK 14 应该包含JEP 358:
JEP 358:有用的 NullPointerExceptions
假设在这段代码中出现了一个 NPE:
Run Code Online (Sandbox Code Playgroud)a.b.c.i = 99;文件名和行号不能准确指出哪个变量为空。
是不是a还是b和c?数组访问和分配也会出现类似的问题。假设在这段代码中出现了一个 NPE:
Run Code Online (Sandbox Code Playgroud)a[i][j][k] = 99;文件名和行号不能准确指出哪个数组组件为空。
是不是a还是a[i]和a[i][j]?描述:
如果更复杂的语句
a.b.c.i = 99;抛出 NPE,消息将剖析该语句并通过显示导致空值的完整访问路径来查明原因:
Exception in thread "main" java.lang.NullPointerException: 
        Cannot read field "c" because "a.b" is null
    at Prog.main(Prog.java:5)
再次:使用 JDK 14 进行测试。
对于 expression
a[i][j][k],也有可能i,j, 或k具有类型Integer并且为空,因此拆箱失败。在现实生活场景中,右边的表达
=也可能具有 NPE 的潜力。我试过 jdk-14.0.1
有用; 它产生一条消息,如
Run Code Online (Sandbox Code Playgroud)Cannot invoke "java.lang.Integer.intValue()" because "i" is null then.当方法在没有调试信息的情况下被编译时,它会使用类似“
<local8>”的东西而不是“i”,但这是不可避免的。
对不起,不,没有一种简单的编程方法来确定哪个变量或方法调用是异常的来源.您可以使用面向方面编程(AOP)之类的东西,例如AspectJ,但这不是语言所固有的,并且通常不会仅仅为了调试目的而合并到程序中.
if (var==null) -> too much worktry { } catch() { }Debugger我知道你不想听到这个,但这些只是做生意的成本.
if (this.superSL.items.get(name).getSource().compareTo(VIsualShoppingList.Source_EXTRA)==0)  {
看到如此多的串联方法调用是不寻常的.我相信你最好的选择就是养成更多打破这些的习惯 - 每行不要低至1个电话,但要少于此.为什么?
1)Correctness- 这些调用中的一个调用返回null是否有效?如果是这样,你应该将其分解,测试并适当地处理它.
2)Understandability- 未来的维护者(包括未来的你)将更容易理解你是否有中间的,命名良好的变量来帮助澄清这一行上发生的事情.
3)Efficiency- 通常当你深入到图形中(将一系列方法调用串联起来)时,你可能需要稍后回到那里.在中间变量中捕获此中间值意味着避免再次进行一个或多个方法调用.
4)Debugging- 如你的问题所示,像这样分割复杂的行简化了调试.通过缩小异常的可能来源.
| 归档时间: | 
 | 
| 查看次数: | 20857 次 | 
| 最近记录: |