详解Java中NullPointerException异常的原因详解以及解决方法
作者:Allen Chou 发布时间:2023-01-22 20:13:28
NullPointerException是当您尝试使用指向内存中空位置的引用(null)时发生的异常,就好像它引用了一个对象一样。
当我们声明引用变量(即对象)时,实际上是在创建指向对象的指针。考虑以下代码,您可以在其中声明基本类型的整型变量x:
int x;
x = 10;
在此示例中,变量x是一个整型变量,Java将为您初始化为0。当您在第二行中将其分配给10时,值10将被写入x指向的内存中。
但是,当您尝试声明引用类型时会发生不同的事情。请使用以下代码:
Integer num;
num = new Integer(10);
第一行声明了一个名为的变量num,但它不包含原始值。相反,它包含一个指针(因为类型Integer是一个引用类型)。既然你还没有说什么指向Java,它将它设置为null,意思是“ 我什么都没有指向”。
在第二行中,new关键字用于实例化(或创建)Integer类型的对象,并为指针变量num分配此对象。您现在可以使用解引用运算符.(点)来引用对象。
在当你声明了一个变量,但是没有创建一个对象,会发生Exception。如果您在创建num对象之前尝试取消引用,则会得到一个NullPointerException。在最琐碎的情况下,编译器将捕获问题并让您知道“num可能尚未初始化”,但有时您编写的代码不会直接创建对象。
例如,您可能使用了如下的方法:
public void doSomething(SomeObject obj) {
//do something to obj
}
在这种情况下,您没有创建对象obj,而是假设它是在doSomething调用方法之前创建的。如果你像这样调用方法:
doSomething(null);
在这种情况下obj为null。如果该方法旨在对传入的对象执行某些操作,则需要抛出异常,因为NullPointerException它是程序错误,程序员将需要该信息用于调试的目的。
或者,可能存在这样的情况:该方法的目的不仅仅是对传入的对象进行操作,因此可以接受空参数。在这种情况下,您需要检查null参数并采取不同的行为。您还应该在文档中解释这一点。例如,doSomething应该最好写成:
/**
* @param obj An optional foo for ____. May be null, in which case
* the result will be ____.
*/
public void doSomething(SomeObject obj) {
if(obj != null) {
//do something
} else {
//do something else
}
}
我如何解决它?
所以你有一个NullPointerException。应该如何解决?让我们举一个简单的例子,它抛出NullPointerException:
public class Printer {
private String name;
public void setName(String name) {
this.name = name;
}
public void print() {
printString(name);
}
private void printString(String s) {
System.out.println(s + " (" + s.length() + ")");
}
public static void main(String[] args) {
Printer printer = new Printer();
printer.print();
}
}
标识空值
第一步是确切地确定导致异常的值。为此,我们需要做一些调试。学习阅读堆栈跟踪很重要。这将显示抛出异常的位置:
Exception in thread "main" java.lang.NullPointerException
at Printer.printString(Printer.java:13)
at Printer.print(Printer.java:9)
at Printer.main(Printer.java:19)
在这里,我们看到在第13行抛出异常(在printString方法中)。查看该行并通过添加日志记录语句或使用调试器来检查哪些值为空。我们发现它s是null,并且调用length方法会抛出异常。我们可以看到程序在s.length()方法中删除时停止抛出异常。
追踪这些值来自哪里
接下来检查此值的来源。按照该方法的调用者,我们可以看到,s与传递printString(name)的print()方法,并this.name为空。
跟踪应设置这些值的位置
在哪里this.name设置?在setName(String)方法中。通过一些更多的调试,我们可以看到根本没有调用此方法。如果调用该方法,请确保检查调用这些方法的顺序,并且在print方法之后不调用set 方法。
这足以为我们提供一个解决方案:在调用printer.setName()之前添加调用printer.print()。
其他修正
该变量可以具有默认值(并且setName可以防止将其设置为null):
private String name = "";
任一print或printString方法可以检查空,例如:
printString((name == null) ? "" : name);
或者您可以设计如下所示的类,以便name 始终具有非null值:
public class Printer {
private final String name;
public Printer(String name) {
this.name = Objects.requireNonNull(name);
}
public void print() {
printString(name);
}
private void printString(String s) {
System.out.println(s + " (" + s.length() + ")");
}
public static void main(String[] args) {
Printer printer = new Printer("123");
printer.print();
}
}
来源:https://blog.csdn.net/Vermont_/article/details/84261442


猜你喜欢
- static void Main(string[] args){ Process proc = null
- 前言本文的多租户是基于多数据库进行实现的,数据是通过不同数据库进行隔离。下面话不多说,来看看详细的介绍:MyCat 基本配置首先针对多租户配
- Android 代码写控件代替XML简单实例简单的一个Button控件的练习。实现代码:Button btn = new Button(Ha
- List<T>是怎么存放元素?我们扒一段List<T>的一段源码来一窥究竟。using System;using S
- 如下图所示,你的UI元素可能小于48dp,图标仅有32dp,按钮仅有40dp,但是他们的实际可操作焦点区域最好都应达到48dp的大小。为使小
- 1.冒泡排序简介冒泡排序(Bubble Sorting)即:通过对待排序的序列从前往后,依次比较相邻元素的值,若发现逆序则交换位置,使较大的
- 本文实例为大家分享了Android实现折线图小工具的具体代码,供大家参考,具体内容如下1.LineChart类public class Li
- Java 8中引入了CompletableFuture类,它是一种方便的异步编程工具,可以处理各种异步操作,如网络请求、文件IO和数据库操作
- Java通过证书访问Https请求创建证书管理器类import java.io.FileInputStream;import java.se
- 什么是Etcd?etcd是一个强大的一致性的分布式键值存储,它提供了一种可靠的方式来存储需要由分布式系统或机器群访问的数据。它优雅地处理网络
- 一、准备工作1、确定电脑上已经成功安装jdk7.0以上版本2、win10操作系统3、maven安装包 下载地址:http://maven.a
- 注解的介绍@ControllerAdvice@ControllerAdvice注解是Spring3.2中新增的注解,学名是Controlle
- 一、关于堆JDK1.8中的PriortyQueue(优先级队列)底层使用了堆的数据结构,而堆实际就是在完全二叉树的基础之上进行了一些元素的调
- 一,哈希表(Hashtable)简述在.NET Framework中,Hashtable是System.Collections命名空间提供的
- 网站优化必做的事情之一,百度ping,主动推送给百度文章添加时调用百度推送方法//保存protected void btnSubmit_Cl
- 先来看一个名为Message的类在这个类中有一段包含在companion object中的代码,需要说一下的是,Kotlin的cl
- 阅读目录:基础Socket编程多线程并发阻塞式同步IO基础在现今软件开发中,网络编程是非常重要的一部分,本文简要介绍下网络编程的概念和实践。
- 本文实例为大家分享了Android实现文字下方加横线的具体代码,供大家参考,具体内容如下public class WhiteTextview
- 现在,让我们找出“如何学习 Java 编程”的答案。通过承认您是初学者这一事实开始您的学习之旅很重要
- mybatis 传入null值解决前端传入两个值,如果其中一个为null时,很多时候我们都很困惑,明明传入的是null,为啥mybatis