Java 教程
- Java - 首页
- Java - 概述
- Java - 历史
- Java - 特性
- Java 与 C++
- JVM - Java 虚拟机
- Java - JDK 与 JRE 与 JVM
- Java - Hello World 程序
- Java - 环境搭建
- Java - 基本语法
- Java - 变量类型
- Java - 数据类型
- Java - 类型转换
- Java - Unicode 系统
- Java - 基本运算符
- Java - 注释
- Java - 用户输入
- Java - 日期与时间
Java 控制语句
- Java - 循环控制
- Java - 决策制定
- Java - If-else
- Java - Switch
- Java - For 循环
- Java - For-Each 循环
- Java - While 循环
- Java - do-while 循环
- Java - Break
- Java - Continue
面向对象编程
- Java - OOPs 概念
- Java - 对象与类
- Java - 类属性
- Java - 类方法
- Java - 方法
- Java - 变量作用域
- Java - 构造函数
- Java - 访问修饰符
- Java - 继承
- Java - 聚合
- Java - 多态
- Java - 重写
- Java - 方法重载
- Java - 动态绑定
- Java - 静态绑定
- Java - 实例初始化块
- Java - 抽象
- Java - 封装
- Java - 接口
- Java - 包
- Java - 内部类
- Java - 静态类
- Java - 匿名类
- Java - 单例类
- Java - 包装类
- Java - 枚举
- Java - 枚举构造函数
- Java - 枚举字符串
Java 内置类
Java 文件处理
Java 错误与异常
- Java - 异常
- Java - try-catch 块
- Java - try-with-resources
- Java - 多重 catch 块
- Java - 嵌套 try 块
- Java - Finally 块
- Java - throw 异常
- Java - 异常传播
- Java - 内置异常
- Java - 自定义异常
Java 多线程
- Java - 多线程
- Java - 线程生命周期
- Java - 创建线程
- Java - 启动线程
- Java - 线程连接
- Java - 线程命名
- Java - 线程调度器
- Java - 线程池
- Java - 主线程
- Java - 线程优先级
- Java - 守护线程
- Java - 线程组
- Java - 关闭钩子
Java 同步
Java 网络
- Java - 网络
- Java - 套接字编程
- Java - URL 处理
- Java - URL 类
- Java - URLConnection 类
- Java - HttpURLConnection 类
- Java - Socket 类
- Java - 泛型
Java 集合
Java 接口
Java 数据结构
Java 集合算法
高级 Java
- Java - 命令行参数
- Java - Lambda 表达式
- Java - 发送邮件
- Java - Applet 基础
- Java - Javadoc 注释
- Java - 自动装箱和拆箱
- Java - 文件不匹配方法
- Java - REPL (JShell)
- Java - 多版本 Jar 文件
- Java - 私有接口方法
- Java - 内部类菱形运算符
- Java - 多分辨率图像 API
- Java - 集合工厂方法
- Java - 模块系统
- Java - Nashorn JavaScript
- Java - Optional 类
- Java - 方法引用
- Java - 函数式接口
- Java - 默认方法
- Java - Base64 编码解码
- Java - Switch 表达式
- Java - Teeing 收集器
- Java - 微基准测试
- Java - 文本块
- Java - 动态 CDS 归档
- Java - Z 垃圾收集器 (ZGC)
- Java - 空指针异常
- Java - 打包工具
- Java - 密封类
- Java - 记录类
- Java - 隐藏类
- Java - 模式匹配
- Java - 紧凑数字格式化
- Java - 垃圾回收
- Java - JIT 编译器
Java 杂项
- Java - 递归
- Java - 正则表达式
- Java - 序列化
- Java - 字符串
- Java - 进程 API 改进
- Java - 流 API 改进
- Java - 增强的 @Deprecated 注释
- Java - CompletableFuture API 改进
- Java - 流
- Java - 日期时间 API
- Java 8 - 新特性
- Java 9 - 新特性
- Java 10 - 新特性
- Java 11 - 新特性
- Java 12 - 新特性
- Java 13 - 新特性
- Java 14 - 新特性
- Java 15 - 新特性
- Java 16 - 新特性
Java API 与框架
Java 类参考
- Java - Scanner
- Java - 数组
- Java - 字符串
- Java - Date
- Java - ArrayList
- Java - Vector
- Java - Stack
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - IdentityHashMap
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection
- Java - Array
Java 有用资源
Java - 空指针异常
在 Java 14 中,引入了一项名为“有帮助的NullPointerException”的新特性。当时它是一个预览特性,后来成为了 JDK 的标准部分。此增强背后的动机是使用更多详细信息丰富 NullPointerException,因为传统的 NullPointerException 仅提供了发生 NullPointerException 的文件名、方法和行号的详细信息。
Java 中传统的空指针异常
在 Java 14 增强 NullPointerException 之前,以下代码将显示如下所示的 NullPointerException 消息
// Create an employee without department Employee emp = new Employee(1,"Robert",null); // get the name of the dept // as name is null, this code will throw a null pointer exception String dept = emp.getDept().getName();
如果使用此代码片段运行,则将产生类似的结果:
Exception in thread "main" java.lang.NullPointerException at com.tutorialspoint.Tester.main(Tester.java:10)
Java 中新的信息性空指针异常
在调试过程中,这样的错误消息没有用。并且在多级嵌套的情况下,检查哪个字段为空导致问题变得更加困难。Java 14 满足了这一需求。在这种情况下,它提供了一个选项来返回如下所示的更有帮助的消息
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.tutorialspoint.Department.getName()" because the return value of "com.tutorialspoint.Employee.getDept()" is null at com.tutorialspoint.Tester.main(Tester.java:10)
在这里我们可以看到,打印了更多信息的消息来帮助调试 getDept() 为空导致的问题。为了在 Java 14 中启用此功能,我们必须使用以下标志运行 Java 代码。
-XX:+ShowCodeDetailsInExceptionMessages
现在在 Java 20 中,不再需要此标志。
针对空对象的帮助性 NullPointerException
在此示例中,我们展示了上面学习的概念。这是一个非常有用的功能,可以调试由空引用引起的错误。在这里,我们创建了两个类 Employee 和 Department。在 main 方法中,我们创建了 Employee 类的对象,但 department 传递为 null。然后我们尝试获取员工的部门名称,这会导致 NullPointerException。在输出中,我们可以看到由JVM引发的信息性空指针异常。
示例
package com.tutorialspoint; import java.util.List; public class Tester { public static void main(String[] args) { // declare an employee without department Employee emp = new Employee(1,"Robert",null); // get department name of null department will // throw a NullPointerException String dept = emp.getDept().getName(); System.out.println(dept); } } class Employee { int id; String name; Department dept; Employee (int id, String name, Department dept){ this.id = id; this.name = name; this.dept = dept; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Department getDept() { return dept; } public void setDept(Department dept) { this.dept = dept; } } class Department { int id; String name; List<Employee> employees; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Employee> getEmployees() { return employees; } public void setEmployees(List<Employee> employees) { this.employees = employees; } }
输出
让我们编译并运行上述程序,这将产生以下结果:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.tutorialspoint.Department.getName()" because the return value of "com.tutorialspoint.Employee.getDept()" is null at com.tutorialspoint.Tester.main(Tester.java:10)
信息性 NullPointerException - 本地空变量
类似于对象引用,局部变量可以为 null。在 Java 14 中,如果使用空局部变量,则 JVM 会将变量名称打印为 <local>,如下所示
String name = null; System.out.println("Length: " + name.length() );
如果使用此代码片段运行,则将产生类似的结果:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "<local1>" is null at com.tutorialspoint.Tester.main(Tester.java:8)
为了打印局部变量的名称,我们在运行程序时必须使用以下标志。
-g
使用此标志会导致以下输出。
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "name" is null at com.tutorialspoint.Tester.main(Tester.java:8)
从 Java 20 开始,不再需要此标志。请参阅以下完整示例
针对空局部变量的帮助性 NullPointerException
在此示例中,我们展示了上面学习的概念来调试空局部引用。在这里,我们创建了一个名为 name 的局部变量,并且我们尝试获取空字符串变量的长度,这将导致 NullPointerException。在输出中,我们可以看到 JVM 引发的信息性空指针异常,其中包含空变量的实际名称。
示例
package com.tutorialspoint; public class Tester { public static void main(String[] args) { String name = null; // accessing property of null local variable // will cause a NullPointerException System.out.println("Length: " + name.length() ); } }
输出
让我们编译并运行上述程序,这将产生以下结果:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "name" is null at com.tutorialspoint.Tester.main(Tester.java:8)