为什么Java不告诉你哪个指针是空的? [英] Why doesn't Java tell you which pointer is null?

查看:182
本文介绍了为什么Java不告诉你哪个指针是空的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直想知道为什么JVM不会告诉你指针(或更确切地说,哪个变量)为null时,一个 NullPointerException 被抛出。



行号不够明确,因为违规行通常可能包含可能导致错误的许多变量。



是否有任何编译器或JVM标志会使这些异常消息更有用?

解决方案

因为当没有可用的名称时,引用总是会发生的。该值被加载到操作数堆栈上,然后传递给解引用它的一个JRE操作码。但是,操作数堆栈没有与空值相关联的名称。它所有的都是'null'。通过一些聪明的运行时跟踪代码,可以导出一个名称,但这会增加有限值的开销。



正因为如此,没有JRE选项会打开额外的空指针异常信息。



在此示例中,引用存储在本地插槽1中,映射到本地变量名称。但是,引用引用发生在invokevirtual指令中,它只在堆栈上看到一个null值,然后抛出一个异常:

  15 aload_1 
16 invokevirtual#5

同样有效的是数组加载,后跟一个取消引用,但在这种情况下,没有名称映射到null值,只是另一个值的索引。

  76 aload 5 
78 iconst_0
79 aaload
80 invokevirtual#5

您无法静态地将名称分配给每个指令 - 此示例生成了大量的字节码,但是您可以看到dereference指令将接收objA或objB,您需要动态跟踪它以报告正确的一个,因为两个变量都流向相同的解引用指令:

 (myflag?objA:objB).toString()


I've always wondered why the JVM doesn't tell you which pointer (or more precisely, which variable) is null when a NullPointerException is thrown.

A line number isn't specific enough because the offending line can often contain numerous variables that could have caused the error.

Is there any compiler or JVM flag that would make these exception messages more useful?

解决方案

It's because the dereference always happens when there is no name available. The value is loaded onto the operand stack, and is then passed to one of the JRE opcodes that dereferences it. However, the operand stack does not have a name to associate with a null value. All it has is 'null'. With some clever runtime tracking code, a name can be derived, but that would add overhead with limited value.

Because of this, there is no JRE option that will turn on extra information for null pointer exceptions.

In this example, the reference is stored in local slot 1, which maps to a local variable name. But the dereference happens in the invokevirtual instruction, which only sees a 'null' value on the stack, and then throws an exception:

15 aload_1
16 invokevirtual #5 

Equally valid would be an array load followed by a dereference, but in this case there is no name to map to the 'null' value, just an index off of another value.

76 aload    5
78 iconst_0
79 aaload
80 invokevirtual #5

You can't allocate the names statically to each instruction either - this example produces a lot of bytecode, but you can see that the dereference instruction will receive either objA or objB, and you would need to track this dynamically to report the right one, as both variables flow to the same dereference instruction:

(myflag ? objA : objB).toString()

这篇关于为什么Java不告诉你哪个指针是空的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆