8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

什么是 NullPointerException,如何修复它?

Chris B. Behrens 2月前

161 0

什么是空指针异常 (java.lang.NullPointerException) 以及导致空指针异常的原因是什么?可以使用哪些方法/工具来确定原因,以便阻止异常导致程序停止运行?

什么是空指针异常( java.lang.NullPointerException )以及其原因是什么?

可以使用哪些方法/工具来确定原因,以便阻止异常导致程序过早终止?

帖子版权声明 1、本帖标题:什么是 NullPointerException,如何修复它?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Chris B. Behrens在本站《regex》版块原创发布, 转载请注明出处!
最新回复 (0)
  • @tomj0101 我完全不明白你为什么会发表这样的评论...但是对于你的第二点,Optional 之前的一个模式是返回 null。这个关键字很好。知道如何防范它是至关重要的。这提供了一种常见的情况以及缓解它的方法。

  • 1. NullPointerException 是一个 RuntimeException,也就是说会在你的程序运行时出现,而不会在编译时出现!:(,但是大多数 IDE 都会帮助你发现这一点。2. 尽量减少在赋值语句中使用关键字 'null'。:)参考网址:

  • 在实例级别(而非类级别)对未初始化对象进行操作将导致 NullPointerException。操作需要特定于实例。如果操作是在类级别,即在未初始化对象上调用静态方法,则不会抛出 NullPointerException 异常。即使原始包装类对象也会抛出 NullPointerException。

  • 另一种情况 NullPointerException 是,当声明一个对象数组,然后立即尝试取消引用其中的元素时,就会发生这种情况。

    String[] phrases = new String[10];
    String keyPhrase = "Bird";
    for(String phrase : phrases) {
        System.out.println(phrase.equals(keyPhrase));
    }
    

    如果比较顺序被反转,则可以避免这种特殊的 NPE;即在保证非空对象上使用.equals

    数组内的所有元素 都初始化为其共同的初始值 ;对于任何类型的对象数组,这意味着所有元素都是 null .

    访问或取消引用 数组中的元素 之前, 必须

    String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
    String keyPhrase = "Bird";
    for(String phrase : phrases) {
        System.out.println(phrase.equals(keyPhrase));
    }
    
  • Java ,您声明的所有变量实际上都是对象(或原语)的“引用”,而不是对象本身。

    当您尝试执行一个对象方法时,引用会要求活动对象执行该方法。但是,如果引用引用的是 NULL(无、零、void、nada),则无法执行该方法。然后,运行时会通过抛出 NullPointerException 来通知您这一点。

    您的引用“指向”空,因此为“空 -> 指针”。

    该对象位于虚拟机内存空间中,访问它的唯一方法是使用 this 引用。请看以下示例:

    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 将释放该对象使用的内存并分配另一个内存。

  • 或者使用异常捕获:如:try { yourRef.someMethod(); } catch (NullPointerException e) { // TODO }

  • NullPointerException 经常发生在调用实例的方法时。比如你声明了一个引用,但是没有让它指向任何实例,那么在调用它的方法时就会抛出 NullPointerException。如: YourClass ref = null; // 或者 ref = anotherRef; // 但是 anotherRef 并没有指向任何实例 ref.someMethod(); // 就会抛出 NullPointerException。一般可以这样解决:在调用方法之前,判断引用是否为 null。如: if (yourRef != null) { yourRef.someMethod(); }

  • 在 Java 中,所有内容(原始类型除外)都以类的形式存在。

    如果您想使用任何对象那么您有两个阶段:

    1. 宣布
    2. 初始化

    例子:

    • 宣言: Object object;
    • 初始化: object = new Object();

    数组概念也一样:

    • 宣言: Item item[] = new Item[5];
    • 初始化: item[0] = new Item();

    如果您没有提供初始化部分,则会 NullPointerException 出现这种情况。

  • 这里使用“未初始化”这个词根本不合适。您给出的示例实际上是“已初始化”,并且已用 null 初始化。对于未初始化的变量,编译器会向您抱怨。

  • 引用 11

    虽然这是一个很好的例子,但我可以问一下它对问题添加了哪些其他答案尚未涉及的内容吗?

  • 空指针异常表明您正在使用一个对象但尚未初始化它。

    例如,下面是一个将在我们的代码中使用它的学生班。

    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");
            }
        }
    }
    
  • 在接受这些“最佳实践”作为真理之前,请先阅读以下内容:satisfice.com/blog/archives/27

  • 在我看来,最好尽可能避免在方法中返回空对象,并在不允许空输入参数时使用注释,以便通过减少代码中的“if(obj==null)”的数量并提高代码的可读性。

  • 首先要做的是在使用可空对象之前,您应该使用 if (obj==null) 检查它是否为空。如果它为空,那么您也应该编写代码来处理它。

  • 值得一提的是,一些 IDE(例如 Eclipse)提供了基于可自定义注释(例如上面列出的 @Nullable)的自动空值分析,并警告潜在错误。还可以根据现有的代码结构推断和生成此类注释(例如 IntelliJ 可以做到这一点)。

  • 在 j2ee 项目中,空指针异常非常常见。有些情况下引用变量会得到空值。因此,您应该正确检查变量初始化。并且在条件语句期间,您应该始终检查标志或引用是否包含空值,例如:- if(flag!=0) { 使用标志的代码 }

  • 已经有很多解释来解释它是如何发生的以及如何解决它,但是您还应该遵循 最佳实践 完全 NullPointerException NullPointerException

    另请参阅: 最佳实践清单

    我想补充的是,非常重要的是充分利用修饰符 final 在 Java 中,只要适用,就使用 \'final\' 修饰符

    概括:

    1. 使用 final 修饰符来强制良好的初始化。
    2. 避免在方法中返回 null,例如在适用时返回空集合。
    3. 使用注释 @NotNull @Nullable
    4. 快速失败并使用断言来避免当空对象不应该为空时在整个应用程序中传播空对象。
    5. 首先对已知对象使用 equals : if("knownObject".equals(unknownObject)
    6. valueOf() 喜欢 toString() .
    7. 使用空安全的 StringUtils 方法 StringUtils.isEmpty(null) .
    8. 在方法中使用 Java 8 Optional 作为返回值,Optional 类提供了一种表示可选值而不是空引用的解决方案。
  • \“NULL 指针是指向无处的指针\”我不同意。空指针不指向无处,而是指向空值。

  • 指针 null 是指向无处的指针。当您取消引用指针时 p ,您会说“给我存储在“p”中的位置的数据”。当 p null 指针时,存储在的位置 p nowhere ,您会说“给我‘无处’位置的数据”。显然,它不能这样做,因此它会抛出一个 null pointer exception .

    一般来说,这是因为某些东西尚未正确初始化。

返回
作者最近主题: