Why can't a null-reference exception name the object that has a null reference?

≯℡__Kan透↙ 提交于 2019-11-29 06:06:15

Exceptions are runtime things, variables are compile time things.

In fact, the variable in your example is an expression. Expressions are not always simple variables. At runtime, the expression will be evaluated and the method will be called on the resulting object. If the value of that expression is null, the runtime will throw a NullReferenceException. Assume the following:

Dim a as New MyObject
Dim b as String = MyObject.GetNullValue().ToString()

What error message should the runtime return if the GetNullValue() method returns null?

For languages like Java that are compiled to bytecode that gets interpreted by a VM, suppose you have a class X with a field x, and its value is null for a certain reference. If you write

x.foo()

the bytecode might look like this:

push Xref           >> top of stack is ref to instance of X with X.x = null
getField x          >> pops Xref, pushes 'null' on the stack
invokeMethod foo    >> pops 'null' -> runtime exception

The point is that the operation that needs a non-null reference on the stack to operate on it, like invokeMethod in the example, cannot and does not know where that null reference came from.

A simple way to catch this for debugging to to place an Assert statement prior to using an object, check for null and output a meaningful message.

In release builds, the variable names are stripped out from the symbols and the code might even be optimized to not have a specific memory location for a variable, but just keep the reference in one of the registers (depending on the scope of the variable usage). Thus, it might not be possible to deduct the name of the variable from the reference location.

In debug build, there's more information available about the variables. However, the exception object needs to work the same way irregardless of the build flavor. Hence, it acts upon the minimum information it can access in any flavor.

A couple of things...

1) when you make your own exceptions keep this in mind (if you are annoyed it it for this someone else will be annoyed at you if you do it for something else). Given that the exception path should not at all be the typical path the time spent making the exception have useful information is well worth it.

2) as a general programming practive adopt this style and you will have far less issues (yes your code will be longer in terms of lines, but you will save a lot of time):

a) never do a.b().c(); do x = a.b(); x.c(); (on separate lines) that way you can see of a was null or if the return of a.b() is null.

b) never pass the return of a method call as a parameter - always pass variables. a(foo()); should be x = foo(); a(x); This one is more for debugging and being able to see the value.

I don't know why environments like .net and Java do not provide a version of the runtime that does have more information on these sorts of exceptions, such as what the index was on an array out of bounds, the name of the variable when it is null, etc...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!