什么是空指针异常(java.lang.NullPointerException),是什么原因导致的?
可以使用哪些方法/工具来确定原因,从而阻止异常导致程序过早终止?
什么是空指针异常(java.lang.NullPointerException),是什么原因导致的?
可以使用哪些方法/工具来确定原因,从而阻止异常导致程序过早终止?
当前回答
在Java中,您声明的所有变量实际上都是对象(或原语)的“引用”,而不是对象本身。
当您尝试执行一个对象方法时,引用会要求活动对象执行该方法。但是如果引用引用的是NULL (nothing, zero, void, nada),那么就没有办法执行方法。然后运行时通过抛出NullPointerException让你知道这一点。
你的引用是“指向”空,因此“空->指针”。
对象存在于VM内存空间中,访问它的唯一方法是使用该引用。举个例子:
public class Some {
private int id;
public int getId(){
return this.id;
}
public setId( int newId ) {
this.id = newId;
}
}
在代码的另一个地方:
Some reference = new Some(); // Point to a new object of type Some()
Some otherReference = null; // Initiallly this points to NULL
reference.setId( 1 ); // Execute setId method, now private var id is 1
System.out.println( reference.getId() ); // Prints 1 to the console
otherReference = reference // Now they both point to the only object.
reference = null; // "reference" now point to null.
// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );
// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...
这是一件很重要的事情——当一个对象没有更多的引用时(在上面的例子中,当reference和otherReference都指向null时),那么这个对象是“不可达的”。我们无法使用它,因此该对象已准备好被垃圾收集,在某个时刻,VM将释放该对象使用的内存,并分配另一个内存。
其他回答
空指针异常表示您正在使用一个对象而没有初始化它。
例如,下面是一个学生类,将在我们的代码中使用它。
public class Student {
private int id;
public int getId() {
return this.id;
}
public setId(int newId) {
this.id = newId;
}
}
下面的代码给出了一个空指针异常。
public class School {
Student student;
public School() {
try {
student.getId();
}
catch(Exception e) {
System.out.println("Null pointer exception");
}
}
}
因为你用的是student,但你忘了初始化它 正确代码如下所示:
public class School {
Student student;
public School() {
try {
student = new Student();
student.setId(12);
student.getId();
}
catch(Exception e) {
System.out.println("Null pointer exception");
}
}
}
已经有很多解释来解释它是如何发生的以及如何修复它,但是您还应该遵循最佳实践来避免nullpointerexception。
参见: 一个很好的最佳实践列表
我还要补充一点,很重要的一点是,充分利用最后一个修饰语。 在Java中使用“final”修饰符
简介:
Use the final modifier to enforce good initialization. Avoid returning null in methods, for example returning empty collections when applicable. Use annotations @NotNull and @Nullable Fail fast and use asserts to avoid propagation of null objects through the whole application when they shouldn't be null. Use equals with a known object first: if("knownObject".equals(unknownObject) Prefer valueOf() over toString(). Use null safe StringUtils methods StringUtils.isEmpty(null). Use Java 8 Optional as return value in methods, Optional class provide a solution for representing optional values instead of null references.
nullpointerexception是当您试图使用指向内存中任何位置(null)的引用时发生的异常,就好像它引用了一个对象一样。调用空引用上的方法或试图访问空引用的字段将触发NullPointerException异常。这些是最常见的方法,但是NullPointerException javadoc页面上列出了其他方法。
可能我能想出的最快的示例代码来说明NullPointerException将是:
public class Example {
public static void main(String[] args) {
Object obj = null;
obj.hashCode();
}
}
在main内部的第一行,我显式地将对象引用obj设置为null。这意味着我有一个引用,但它不指向任何对象。在此之后,我尝试通过调用对象上的方法来将引用视为指向对象。这将导致NullPointerException,因为在引用所指向的位置中没有代码要执行。
(这是一个技术细节,但我认为值得一提:指向null的引用与指向无效内存位置的C指针不同。空指针字面上不指向任何地方,这与指向一个恰好无效的位置有微妙的不同。)
这就像你试图访问一个为空的对象。考虑下面的例子:
TypeA objA;
此时,您刚刚声明了该对象,但尚未初始化或实例化。无论何时你试图访问其中的任何属性或方法,它都会抛出NullPointerException,这是有意义的。
请看下面的例子:
String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
空指针是指不指向任何地方的指针。当你对指针p进行解引用时,你说“给我存储在p中的位置的数据”。当p是一个空指针时,存储在p中的位置是无处不在的,你是在说“给我无处位置的数据”。显然,它不能这样做,所以它抛出一个空指针异常。
一般来说,这是因为某些东西没有正确地初始化。