Java中的空指针异常

Java中的空指针异常Java 中的空指针异常一 什么是空指针异常 1 1 异常的分类 1 2 空指针异常引入 1 3 空指针异常说明二 Java 中的 null 三 空指针产生的常见情况及避免办法 3 1 字符串常量未初始化 比较时导致空指针异常 3 2 接口类型的对象没有使用具体的类进行初始化导致空指针异常 3 3 参数类型为包装类型 使用时自动拆箱导致空指针异常 3 4 对象为空 但未判空导致空指针异常 3 5 对 key value 不能为 null 的容器 put 为 null 的 key value 值导致空指针异常 3 6 方法或者远程服务返回的 list 不是

一、什么是空指针异常?

1.1 异常的分类

在这里插入图片描述
NullPointerException是RuntimeException的一个子类,这是运行时异常,在编译时期不会触发。

1.2 空指针异常引入

Java是没有指针的,所以我们常说”Java 指针”就是指”Java 的引用”。空指针就是空引用,Java空指针异常就是引用本身为空,但却调用了方法,这个时候就会出现空指针异常。

成员变量和方法是属于对象的(除去静态的),在对象中才存在相对应的成员变量和方法,然后通过对象去调用这些成员变量和方法。

而对于空指针来说,它是不指向任何对象的,也就是没有所谓的成员变量和方法,这个时候去调用某些属性和方法时,就一定会出现空指针异常。

1.3 空指针异常说明

/ * @author QHJ * @date 2021/11/25 14:42 * @description: */ public class NullPointTest { 
    private int a = 1; private int b = 2; public static void main(String[] args) { 
    NullPointTest nullPointTest1 = new NullPointTest(); System.out.println(nullPointTest1.a); System.out.println(nullPointTest1.sum()); NullPointTest nullPointTest2 = null; System.out.println(nullPointTest2.b); System.out.println(nullPointTest2.sum()); } public String sum(){ 
    return "这是sum()方法..."; } } 

在这里插入图片描述
说明:对象 nullPointTest1 是通过默认的无参构造方法实例出来的 NullPointTest 对象;对象 nullPointTest2 只是声明了一个空对象,并没有指向实际的对象,它没有响应的成员变量和方法,当调用不属于它的成员变量和方法时,引发空指针异常。

二、Java中的null

null是Java中一个很重要的概念,null 设计的初衷是为了表示一些缺失的东西,比如缺失的用户、资源或一些其他东西。

  • 首先,null是关键字,像public、static、final。它是大小写敏感的,你不能将 null 写成 Null 或 NULL,编译器将不能识别它们然后报错。
  • null是任何引用类型的默认值,不严格的说是所有object类型的默认值。就像你创建了一个布尔类型的变量,它将 false 作为自己的默认值,Java中的任何引用变量都将 nul l作为默认值。这对所有变量都是适用的,如成员变量、局部变量、实例变量、静态变量(但当你使用一个没有初始化的局部变量,编译器会警告你)。
  • null既不是对象也不是一种类型,它仅是一种特殊的值,你可以将其赋予任何引用类型,你也可以将 null 转化成任何类型。
  • null可以赋值给引用变量,但不能将null赋给基本类型变量。例如int、double、float、boolean。编译器将会报错。

    当直接将null赋值给基本类型,会出现编译错误。但是如果将null赋值给包装类object,然后将object赋给各自的基本类型,编译器不会报,但是你将会在运行时期遇到空指针异常。这是Java中的自动拆箱导致的。

  • 任何含有null值的包装类在Java拆箱生成基本数据类型时候都会抛出一个空指针异常。
    在这里插入图片描述

  • 如果使用了带有 null 值的引用类型变量,instanceof 操作将会返回 false。
    Integer iAmNull = null; if(iAmNull instanceof Integer){ 
          System.out.println("iAmNull is instance of Integer"); }else{ 
          System.out.println("iAmNull is NOT an instance of Integer"); } 结果:iAmNull is NOT an instance of Integer 
  • 不能调用非静态方法来使用一个值为 null 的引用类型变量。但是可以调用静态方法里值为 null 的引用类型变量,因为静态方法使用静态绑定,不会抛出空指针异常。
    在这里插入图片描述

  • 可以将 null 传递给方法使用,这时方法可以接收任何引用类型,例如public void print(Object obj)可以这样调用print(null)。从编译角度来看这是可以的,但结果完全取决于方法。null 安全的方法,如在这个例子中的 print() 方法,不会抛出空指针异常,只是优雅的退出。如果业务逻辑允许的话,推荐使用 null 安全的方法。
    在这里插入图片描述

  • 可以使用 = = 或者 != 操作来比较 null 值,但是不能使用其他算法或者逻辑操作,例如小于或者大于。在Java中 null == null 将返回true。

三、空指针产生的常见情况及避免办法

3.1 字符串常量未初始化,比较时导致空指针异常

  • 出现空指针
    String str = null; // 不推荐——把变量放在常量前,当变量为空时,运行时报空指针 if (str.equals("zhangsan")){ 
          System.out.println("相等"); }else{ 
          System.out.println("不相等"); } 

    在这里插入图片描述

  • 避免空指针
    String str = null; // 推荐——把常量放在变量前,运行时不会报错 if ("zhangsan".equals(str)){ 
          System.out.println("相等"); }else { 
          System.out.println("不相等"); } 

    在这里插入图片描述

3.2 接口类型的对象没有使用具体的类进行初始化导致空指针异常

  • 出现空指针
    // list1 没有使用具体的类进行初始化,在使用时会报错 List list1; // list2 没有使用具体的类进行初始化,报空指针 List list2 = null; System.out.println("不能直接使用list1..."); System.out.println("list2:" + list2.isEmpty()); 

    在这里插入图片描述

  • 避免空指针
    List list3 = new ArrayList(); System.out.println("list3:" + list3.isEmpty()); 

    在这里插入图片描述

3.3 参数类型为包装类型,使用时自动拆箱导致空指针异常

  • 出现空指针
    Integer a = 1; Integer b = null; sum(a, b); public static String sum(Integer a, Integer b){ 
          System.out.println(a + b); return "这是sum()方法..."; } 

    在这里插入图片描述

    注意: null 值不能转换为基本数据类型!

  • 避免空指针
    Integer a = 1; Integer b = null; // 避免空指针——及时判空  if (a != null && b != null){ 
          sum(a, b); }else{ 
          System.out.println("参数不允许为空值!"); } public static String sum(Integer a, Integer b){ 
          System.out.println(a + b); return "这是sum()方法..."; } 

    在这里插入图片描述

3.4 对象为空,但未判空导致空指针异常

  • 出现空指针
    UserEntity userEntity = null; System.out.println(userEntity.getName() + "\t" +userEntity.getAge()); 

    在这里插入图片描述

  • 避免空指针
    UserEntity userEntity = null; if (userEntity != null){ 
          System.out.println(userEntity.getName() + "\t" +userEntity.getAge()); }else { 
          System.out.println("对象不能为空哦!"); } 

    在这里插入图片描述

3.5 对key、value不能为null的容器put为null的key、value值导致空指针异常

  • 出现空指针
    Map<String, String> map = new Hashtable<>(); map.put("name:", "张三"); map.put("age:", "23"); map.put("nick:", null); map.put("", ""); System.out.println(map); 

    在这里插入图片描述

  • 避免空指针
    Map<String, String> map = new HashMap<>(); map.put("name:", "张三"); map.put("age:", "23"); map.put("nick:", null); map.put("", ""); System.out.println(map); 

    在这里插入图片描述

3.6 方法或者远程服务返回的list不是空而是null,没有进行判空,就直接调用该list的方法导致空指针异常

  • 出现空指针
    // 假设是通过方法或远程调用获得的list List list = null; Stream stream = list.stream().filter(s -> s.equals("zhangsan")); System.out.println(stream); 

    在这里插入图片描述

  • 避免空指针
    // 假设是通过方法或远程调用获得的list List list = null; if (list != null){ 
          Stream stream = list.stream().filter(s -> s.equals("zhangsan")); System.out.println(stream); }else { 
          System.out.println("获取的集合list不能为空!"); } 

    在这里插入图片描述

四、总结和技巧

在遇到空指针错误时,要重点关注报错发生的所在行,通过空指针异常产生的两条主要原因(变量未初始化和对象为空)诊断具体的错误,主要注意以下几点:

  1. 检查使用之前是否进行了初始化
  2. 尽量避免在函数中返回 null 值,如果必须要返回 null 值,一定要给出详细的注释信息;
  3. 外部传值时,一定要及时的进行判空处理(除非有明确的说明可以为 null );
  4. 使用 equals() 方法时,要遵循 "常量在前变量在后"的原则;
  5. 使用 valueOf() 替换toString()
  6. 通过返回空的 Collection 或 Array 来替代 null 值;
  7. 使用注解 @NotNull、@Nullable;
  8. 定义合理的默认值,遵守约定(比如设置默认值,设置是否允许为空,从而形成合理的约定);
  9. 从数据库取数据,可以约束哪些字段不能为空。

Java中的8种数据类型,变量的值可以有其默认值,假如没有对其正常赋值,Java虚拟机是不能正确编译通过的,所以使用基本数据类型一般是不会引起空指针异常的。也就是说,在实际开发中大多数的空指针异常主要与对象的操作相关。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/201838.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午8:30
下一篇 2026年3月20日 上午8:30


相关推荐

  • linux下 安装企业微信

    linux下 安装企业微信以下步骤在 ubuntu18 04 环境下测试 1 安装 Deepin Wine 环境 1 1 把 Deepin wine for ubuntuGit 仓库的内容克隆到本地 gitclonehttp github com wszqkzqk deepin wine ubuntu gitcddeepin wine ubuntu1 2 安装 chmod x install 2 8 22 shsudo install 2 8 22 sh2 安装 De

    2026年3月18日
    3
  • SpringBootTest无法启动

    SpringBootTest无法启动Suppressed:java.lang.IllegalStateException:Unabletofinda@SpringBootConfiguration,youneedtouse@ContextConfigurationor@SpringBootTest(classes=…)withyourtestatorg.springframework.util.Assert.state(Assert.java:76)解决方法将test目录与java目录保持一致,编译完成之

    2022年5月20日
    33
  • 哈佛幸福课笔记!「建议收藏」

    哈佛幸福课笔记!「建议收藏」https://www.bilibili.com/video/BV1Gs411o71d?p=1记笔记的小天才!我应该多想想,如何将课程中的知识,运用到实际生活中,而不是只记录下来!Part1theimportanceofsilence,安静时刻的重要性,无论在家里还是,课堂,公司享受安静embracesilence(可能是这个课程最重要的)真正的学习,发生在你尝试分辨,什么是真正重要的,什么舍弃,什么保留,而这些都发生在安静自省时例子:连续不断进入迷宫的老鼠,

    2022年7月25日
    11
  • SOP的定义和企业应用[通俗易懂]

    SOP的定义和企业应用[通俗易懂]SOP的定义和企业应用目录1    SOP的概念描述……………………………………………………………………………………………11.1    SOP是一种程序……………………………………..

    2022年5月26日
    61
  • qtabwidget tab样式_qt geometry

    qtabwidget tab样式_qt geometrytabWidget=newQTabWidget();tabWidget->setUsesScrollButtons(true);//使QTabWidget显示滚动条tabWidget->setTabsClosable(true);//设置tab的关闭选项tabWidget->setTabsClosable(true)…

    2026年2月22日
    3
  • 网线的交叉线和直通线原理

    网线的交叉线和直通线原理转载自 http://yxy73622.blog.163.com/blog/static/1733173742012231114013341/正线(标准568B):两端线序一样,线序是:白橙,橙,白绿,蓝,白蓝,绿,白棕,棕。反线(568A):一端为正线的线序,另一端为:白绿,绿,白橙,蓝,白蓝,橙,白棕,棕。T568A标准连线顺序从左到右依次为:1-绿白、2-绿、3-橙白、4

    2022年6月19日
    32

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号