Java 如何在引发NullPointerException时查找null obejct
在java中,当抛出NullPointerException时,是否有任何方法可以知道有问题对象的类的名称?当有问题的java语句中有很多可以为null的对象时,这将有助于调试代码。试图解开一些字眼: 对象永远不为空!它是一个引用,可以是Java 如何在引发NullPointerException时查找null obejct,java,Java,在java中,当抛出NullPointerException时,是否有任何方法可以知道有问题对象的类的名称?当有问题的java语句中有很多可以为null的对象时,这将有助于调试代码。试图解开一些字眼: 对象永远不为空!它是一个引用,可以是null。引用有一个类型——要么是声明的变量,要么是更复杂的表达式(例如方法调用) 当您尝试取消引用null的引用时,会发生null异常,这意味着该引用不指向对象。无法获取不存在的对象的类。我想,对于那个NPE,您想检索引用null的表达式类型,是吗 唯一可以得
null
。引用有一个类型——要么是声明的变量,要么是更复杂的表达式(例如方法调用)
当您尝试取消引用null
的引用时,会发生null异常,这意味着该引用不指向对象。无法获取不存在的对象的类。我想,对于那个NPE,您想检索引用null
的表达式类型,是吗
唯一可以得到(并且应该分析)的是发生NPE的源代码行。这是异常堆栈跟踪的一部分。有了这些信息,您可以调试代码。尝试解开一些字眼:
对象永远不为空
!它是一个引用,可以是null
。引用有一个类型——要么是声明的变量,要么是更复杂的表达式(例如方法调用)
当您尝试取消引用null
的引用时,会发生null异常,这意味着该引用不指向对象。无法获取不存在的对象的类。我想,对于那个NPE,您想检索引用null
的表达式类型,是吗
唯一可以得到(并且应该分析)的是发生NPE的源代码行。这是异常堆栈跟踪的一部分。有了这些信息,您可以调试代码。看看这些代码和注释:
public class Main {
public static void main(final String args[])
{
Main test = new Main();
test.testNull();
System.out.println("My program still works!"); //this WILL NOT be printed asn NPE is thrown in testNull() and it's not caught - this will result in stopping the program.
}
private void testNull()
{
String aaa = null;
aaa.charAt(1); //here you'll get a NullPointerException because there 'aaa' doesn't reference any existing object.
}
}
输出如下所示:
Exception in thread "main" java.lang.NullPointerException //error caught in method "main", you also have the exception class shown.
at Main.testNull(Main.java:26) //null was found in file Main.java in method testNull on line 26.
at Main.main(Main.java:19) //the method testNull was called from method main - line 19.
编辑:
你可以这样做:
public static void main(final String args[])
{
Main test = new Main();
try
{
test.testNull();
}
catch (final NullPointerException e) //catch the NPE
{
e.printStackTrace(); //print info about the cause.
//do some other stuff to handle the exception
}
System.out.println("My program still works!"); //this WILL be printed
}
输出:
java.lang.NullPointerException
at Main.testNull(Main.java:25)
at Main.main(Main.java:13)
My program still works!
请查看此代码和注释:
public class Main {
public static void main(final String args[])
{
Main test = new Main();
test.testNull();
System.out.println("My program still works!"); //this WILL NOT be printed asn NPE is thrown in testNull() and it's not caught - this will result in stopping the program.
}
private void testNull()
{
String aaa = null;
aaa.charAt(1); //here you'll get a NullPointerException because there 'aaa' doesn't reference any existing object.
}
}
输出如下所示:
Exception in thread "main" java.lang.NullPointerException //error caught in method "main", you also have the exception class shown.
at Main.testNull(Main.java:26) //null was found in file Main.java in method testNull on line 26.
at Main.main(Main.java:19) //the method testNull was called from method main - line 19.
编辑:
你可以这样做:
public static void main(final String args[])
{
Main test = new Main();
try
{
test.testNull();
}
catch (final NullPointerException e) //catch the NPE
{
e.printStackTrace(); //print info about the cause.
//do some other stuff to handle the exception
}
System.out.println("My program still works!"); //this WILL be printed
}
输出:
java.lang.NullPointerException
at Main.testNull(Main.java:25)
at Main.main(Main.java:13)
My program still works!
不幸的是,没有
您是指值的声明类型。它仅在编译时可用(通常向IDE报告)
编译成字节码后,声明信息被删除,因此即使是int
也可以包含字符串。这就是为什么方法签名如此重要 不幸的是没有
您是指值的声明类型。它仅在编译时可用(通常向IDE报告)
编译成字节码后,声明信息被删除,因此即使是int
也可以包含字符串。这就是为什么方法签名如此重要 在SeelenVirtuse的回答中添加:
如果您想找出导致NullPointerException的确切原因,请首先在堆栈跟踪中找到引发异常的行。这通常是跟踪中的顶行
假设是这一行:
vfoo = foo.ffoo(bar.fbar(),foo2);
这里可能的罪犯是foo或bar。vfoo无法抛出异常,因为它没有被取消引用,与foo 2相同。它不能在foo.ffoo()或bar.fbar()函数中,因为堆栈跟踪不会指向此行,但会在这些函数中显示异常。所以剩下的就是foo和bar,因为它们都被解除了引用。
因此,要找出这其中的哪一个,只需将语句分开:
temp = bar.fbar();
vfoo = foo.ffoo(temp,foo2);
现在堆栈跟踪将指向一行或另一行,您将知道bar或foo为null
您也可以在声明之前执行以下操作:
System.out.println("bar exists: "+(bar!=null));
System.out.println("foo exists: "+(foo!=null));
最后一点要谈的是:变量何时被取消引用
只有对象可以被取消引用,所以像int、float、double、char、byte之类的原语既不能为Null,也不能被取消引用。
使用时,对象将被取消引用。运算符访问对象的字段或函数(例如foo.bar()或foo.ibar=5)。此外,当您使用支持自动取消装箱的对象(例如整数、浮点、双精度、字符等)并使用任何数学或逻辑运算符(例如+、-、*、/、&、&&、&、|、|、!)时,它也会被取消引用。基本上,每次尝试访问对象的内容时,都是这样,而不仅仅是对对象的引用。补充Seelenvirtuose的答案:
如果您想找出导致NullPointerException的确切原因,请首先在堆栈跟踪中找到引发异常的行。这通常是跟踪中的顶行
假设是这一行:
vfoo = foo.ffoo(bar.fbar(),foo2);
这里可能的罪犯是foo或bar。vfoo无法抛出异常,因为它没有被取消引用,与foo 2相同。它不能在foo.ffoo()或bar.fbar()函数中,因为堆栈跟踪不会指向此行,但会在这些函数中显示异常。所以剩下的就是foo和bar,因为它们都被解除了引用。
因此,要找出这其中的哪一个,只需将语句分开:
temp = bar.fbar();
vfoo = foo.ffoo(temp,foo2);
现在堆栈跟踪将指向一行或另一行,您将知道bar或foo为null
您也可以在声明之前执行以下操作:
System.out.println("bar exists: "+(bar!=null));
System.out.println("foo exists: "+(foo!=null));
最后一点要谈的是:变量何时被取消引用
只有对象可以被取消引用,所以像int、float、double、char、byte之类的原语既不能为Null,也不能被取消引用。
使用时,对象将被取消引用。运算符访问对象的字段或函数(例如foo.bar()或foo.ibar=5)。此外,当您使用支持自动取消装箱的对象(例如整数、浮点、双精度、字符等)并使用任何数学或逻辑运算符(例如+、-、*、/、&、&&、&、|、|、!)时,它也会被取消引用。基本上每次你尝试交流时都是这样