当前位置: 首页 > news >正文

NullPointerException 空指针异常,为什么老是遇到?

网罗开发(小红书、快手、视频号同名)

  大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


文章目录

    • 摘要
    • 引言
    • 问题分析
    • 常见解决方案
      • 1. 手动判空(最朴素的方法)
      • 2. 使用 `Optional`(推荐写法)
      • 3. 使用 Lombok 的 `@NonNull` 注解(开发时防御)
    • 实际开发场景举例
      • 场景 1:数据库查询结果为空
      • 场景 2:第三方接口返回字段缺失
      • 场景 3:集合取值前检查
    • QA 环节
    • 总结

摘要

在 Java 开发中,NullPointerException(空指针异常) 是最常见也是最让人头疼的异常之一。它通常出现在你操作了一个还没有初始化的对象时。很多同学写项目,尤其是初学时,总会碰到 “空指针” 的报错,明明逻辑没什么问题,结果程序直接崩掉。今天我们就用一个简单的例子,聊聊空指针出现的原因、常见的解决方法,并写个小 Demo 帮助你更好地理解。

引言

Java 的对象在使用之前必须先实例化,这跟 Python、JavaScript 等动态语言有点不一样。在动态语言中,即使你没有定义变量也可能会被“兜底”处理掉,但在 Java 里,一旦你直接对 null 调用方法,就会触发 NullPointerException
所以空指针本质上就是:你把不存在的东西,当作存在的对象来用

问题分析

来看下面这段代码:

public class NullPointerDemo {public static void main(String[] args) {String s = null;System.out.println(s.length());}
}

运行结果:

Exception in thread "main" java.lang.NullPointerExceptionat NullPointerDemo.main(NullPointerDemo.java:4)

这里 snull,却调用了 s.length(),于是程序直接抛出了空指针异常。

很多新手在实际开发中,可能是在处理请求参数、数据库返回值、或者第三方接口返回对象时,忘记做空值检查,就导致了这种问题。比如:

  • 数据库没查到数据返回 null
  • HTTP 接口没返回期望字段;
  • 集合里没有元素直接调用 .get(0)
  • Spring 注入失败,Bean 没有实例化。

常见解决方案

1. 手动判空(最朴素的方法)

public class NullPointerCheck {public static void main(String[] args) {String s = null;if (s != null) {System.out.println(s.length());} else {System.out.println("字符串为空,无法计算长度");}}
}

解释:
这是最常见的防御性写法。在调用对象的方法之前先做空值判断,可以避免异常直接崩掉程序。

2. 使用 Optional(推荐写法)

Java 8 引入了 Optional,它的核心思想是:把可能为空的对象用一个容器包起来,强制你用显式的方式处理空值

import java.util.Optional;public class NullPointerOptional {public static void main(String[] args) {String s = null;// 用 Optional 包裹String result = Optional.ofNullable(s).map(String::length)   // 如果不为 null,就计算长度.map(Object::toString) // 转成字符串.orElse("默认值");      // 如果为 null,返回默认值System.out.println(result);}
}

输出:

默认值

解释:
相比传统 if (obj != null)Optional 写法更优雅,更函数式,也能让代码逻辑更清晰。

3. 使用 Lombok 的 @NonNull 注解(开发时防御)

Lombok 提供了一个 @NonNull 注解,可以在方法参数或成员变量上标记。被标记的参数如果传入了 null,在运行时会自动抛出 NullPointerException,帮助你更快定位问题。

import lombok.NonNull;public class NullPointerLombok {public static void printLength(@NonNull String s) {System.out.println(s.length());}public static void main(String[] args) {String value = null;printLength(value); // 这里会直接抛 NullPointerException}
}

输出:

Exception in thread "main" java.lang.NullPointerException: s is marked non-null but is null

解释:
这不是帮你避免空指针,而是 在第一时间发现空指针,防止错误逻辑蔓延到更深层。

实际开发场景举例

场景 1:数据库查询结果为空

User user = userRepository.findById(123);
if (user != null) {System.out.println(user.getName());
} else {System.out.println("用户不存在");
}

场景 2:第三方接口返回字段缺失

ApiResponse response = apiClient.getUserInfo();
Optional.ofNullable(response.getData()).map(UserData::getNickname).ifPresentOrElse(nickname -> System.out.println("昵称:" + nickname),() -> System.out.println("接口返回数据为空"));

场景 3:集合取值前检查

List<String> list = new ArrayList<>();
if (!list.isEmpty()) {System.out.println(list.get(0));
}

QA 环节

Q:为什么有时候明明加了 @Autowired,还是报空指针?
A:这通常是因为 Spring 的 Bean 没有被扫描到,或者你在非 Spring 管理的类里使用了 Bean。解决办法是检查包扫描路径,或者用 @Component / @Service 标注类。

Q:Optional 会不会影响性能?
A:Optional 本质上是个对象包装,开销很小,一般业务代码中性能损耗可以忽略不计。

总结

  • 空指针异常本质上就是你在操作 null 对象
  • 最简单的方法是 手动判空
  • 推荐使用 Optional 让代码更简洁。
  • 可以用 Lombok 的 @NonNull 提前发现空值问题。
  • 在实际项目中,不同场景需要结合判空逻辑,养成良好的防御性编程习惯。
http://www.dtcms.com/a/357176.html

相关文章:

  • 嵌入式Ubuntu22.04安装过程详解实现
  • Oracle SQL性能调优之魂:深入理解索引原理与优化实践
  • 智能接听,破局高峰占线:云蝠AI客服重塑企业服务新范式
  • 【Spring底层分析】Spring AOP补充以及@Transactional注解的底层原理分析
  • 球型摄像机实现360°无死角
  • 【前端教程】从基础到专业:诗哩诗哩网HTML视频页面重构解析
  • 技术干货|Prometheus告警及告警规则
  • APM32芯得 EP.31 | APM32F402 HC-SR04超声测距经典操作:波形输出与滤波
  • 微算法科技(NASDAQ:MLGO)一种基于FPGA的Grover搜索优化算法技术引领量子计算
  • PCIe 6.0配置与地址空间架构:深入解析设备初始化的核心机制
  • C#实现OPC客户端
  • 《Password Guessing Using Random Forest》论文解读
  • system论文阅读--HPCA25
  • Excel Word Pdf 格式转换
  • ubuntu 安装 vllm
  • 电平移位器的原理
  • 群核科技--SpatialGen
  • pytest使用allure测试报告
  • Pytest 插件方法:pytest_runtest_makereport
  • 多方调研赋能AI+智慧消防 豪越科技人工智能创新获认可
  • 【网络安全领域】边界安全是什么?目前的发展及应用场景
  • java基本类型关键字
  • EasyExcel处理大数据量导出
  • 新手法务合同审查,有什么建议?
  • 单点登录(SSO)前端(Vue2.X)改造
  • 关于锁相放大器(LIA)的系统论文研究(重点于FPGA部分)
  • 设计模式:装饰模式(Decorator Pattern)
  • iOS开发之苹果系统包含的所有字体库
  • 最小生成树——Kruskal
  • 【机器学习入门】3.1 关联分析——从“购物篮”到推荐系统的核心逻辑