一位技术主管问我以下问题:
他创建了一个类,声明了一个对象并对其进行了初始化。但在某些情况下,我们可能会得到“空引用”异常。
他评论说这种异常有 1000 个可能的原因,并让我猜测一个原因。
我无法弄清楚。什么是(是)原因,我们可能会得到这样的异常?
10 回答
- 您使用了明确设置为 null 的对象引用,或者
- 您使用了已隐式设置为 null 的对象引用,或者
- 在您的代码或您调用的代码中的某处,有该语句
throw new NullReferenceException()
(顺便说一句,您不应该这样做)。我不知道这是否重要,因为它不是真正的空引用。
我想不出任何其他 997 个原因。
编辑:谢谢,马克拜尔斯,第 3 点。
如果它是一个多线程应用程序,那么其他一些线程可能会出现并将对象设置为空引用。
堆栈溢出?
{◕◡◕}
我能想到的几种方法:
- 构造函数可以
NullReferenceException
在完成之前抛出 a 。 - 当您访问一个属性时,该属性可以抛出一个
NullReferenceException
. - 如果你有一个
try { } finally { }
周围的代码,如果它抛出一个异常 finally 运行并且 finally 中的代码可能会抛出一个NullReferenceException
. - 在赋值过程中可能存在隐式转换,并且转换代码会抛出
NullReferenceException
.
这是最后的示例代码:
class Foo {}
class Bar
{
public static implicit operator Foo(Bar bar)
{
throw new NullReferenceException();
}
}
class Program
{
public static void Main()
{
Foo foo = new Bar(); // This causes a NullReferenceException to be thrown.
}
}
他创建了一个类,声明了一个对象并对其进行了初始化。但在某些情况下,我们可能会得到“空引用”异常。他评论说这种异常有 1000 个可能的原因,并让我猜测一个原因。我无法弄清楚。什么是(是)原因,我们可能会得到这样的异常?
直截了当的回答:我会告诉面试官你不能调试你看不到的代码。要求查看有问题的代码行和调试器。
不那么直截了当的答案:假设你的面试官不是白痴,他可能会因为你的调试技能而感觉到你。如果您收到糟糕的错误报告,您是立即举起双臂投降,还是尝试解决它。
猜测不是调试错误的可接受方式。第一步是在您的机器上重现该错误。
它是否可靠地再现?如果是,请取出您的调试器。
如果不是,您可以间歇性地或不确定地重现它吗?异常是在代码的不同位置还是在不同的线程上随机发生?如果是,您可能有某种竞争条件,或者可能是指针损坏。
如果不是,请询问发现该错误的人是否可以重现。当你按照与最初发现错误的人相同的步骤进行操作时,你能重现吗?如果是,请参见上文。
如果不是,是否有环境差异?配置文件?数据库中的数据?环境是否使用最新的服务包、软件更新等进行了更新?
你不能给面试官一个答案,但你可以给他一个你最终得到答案的步骤列表。
不是专家,只是一个疯狂的猜测,内存不足?
您始终可以将某些内容初始化为空值;
public class MyClass
{
// initialized to null
private string _myString = null;
// _myString is initialized, but this throws null reference
public int StringLength { get { return _myString.Length(); } }
}
在多线程代码中,可以在创建对象之后访问变量,但在将变量分配给它的位置之前。
有问题的对象可能包含其他未在主对象的构造函数中初始化的对象。该问题未指定空引用异常发生的地点或时间。
999 去。
我认为面试官实际上是在寻找您将如何解决问题,即您将采取哪些故障排除步骤来解决可能由一千种不同事物引起的问题。