常见的NullPointerException总结
NullPointerException在这里简称为NPE
通过一些实例总结下常见的NPE问题:
1. 自动拆箱抛NPE
实体类:
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
测试类:
public class NPEDemo {
public static void main(String[] args) {
method();
}
static int method(){
User user = new User();
System.out.println("---" + new User().toString());
return user.getAge();
}
}
出错:
---User [name=null, age=null]
Exception in thread "main" java.lang.NullPointerException
at finaldemo.NPEDemo.method(NPEDemo.java:12)
at finaldemo.NPEDemo.main(NPEDemo.java:6)
分析错误原因:
包装类型为 null 时,进行自动转换为基本数据类型报错。
return user.getAge();
其中user不为空,但是user.getAge()为空(Integer类型)
而且method方法需要的返回类型是int,此时就自动进行了拆箱转换,即从Integer到int类型的转换。
而从Integer到int类型转换的时候user.getAge().intValue(); 会报空指针异常
解决方案:
返回之前进行判断与处理或者改为相同类型。
2. 级联调用易产生NPE
这段代码有点容易迷惑人,因为它进行了集合元素的 isEmpty 判断,按说不会出问题了吧。看代码:
static void method1() {
List<User> list = new ArrayList<User>();
list.add(new User());
if (!CollectionUtils.isEmpty(list)) {
for (User user : list) {
System.out.println("userid:" + user.getAge().toString());
}
}
}
报错:
Exception in thread "main" java.lang.NullPointerException
at finaldemo.NPEDemo.method1(NPEDemo.java:18)
at finaldemo.NPEDemo.main(NPEDemo.java:9)
分析错误原因:
其实就是尽管你在之前做了对象不为空的判断,但你并不能保证对象中的值不为空,而且这时候去级联调用就会抛 NPE 。
手册中关于 NPE 的描述:
防止 NPE 是调用者的责任。即使被调用方法返回空集合或者空对象,对调用者来说,也并非高枕无忧,必须考虑到远程调用失败、序列化失败、运行时异常等场景返回 null 的情况。 集合里的元素即使 isEmpty,取出的数据元素也可能为 null。 级联调用 obj.getA().getB().getC();一连串调用,易产生 NPE
3. 关于 Equals
这是日常开发中用于相等比较使用最多的方法了吧,因为当年谁没被 == 坑过阿。现在一般我们都会这么写:
public class NPEDemo {
public static void main(String[] args) {
method1();
}
static void method1() {
User user = new User();
user.getName().equals("men");
}
}
分析错误原因:
一不小心使用了 null 值调用了 Equals 方法。
解决方案:
很简单咯,这么写:"mafly".equals(user.getName());
equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。
4.Map 下的 NPEMap 应该是我们开发中使用最频繁的了,最常用的可能有 HashMap、ConcurrentHashMap 这俩了,可能会一不留神写出这样的代码:
public class NPEDemo {
public static void main(String[] args) {
method1();
}
static void method1() {
User user = new User();
Map<Integer, Object> map = new HashMap<Integer, Object>();
map.put(user.getAge(), user.getName());
// System.out.println("---" + map);
Map<Integer, Object> map2 = new ConcurrentHashMap<Integer, Object>();
map2.put(user.getAge(), user.getName());
}
}
报错:
Exception in thread "main" java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.put(Unknown Source)
at finaldemo.NPEDemo.method1(NPEDemo.java:21)
at finaldemo.NPEDemo.main(NPEDemo.java:12)
分析错误原因:
可能我们知道 ConcurrentHashMap 的 K/V 都不能为空,但我们有时候并不知道传进来的值是否为空。
解决方案:
设置时做下检验,对它的特性正确理解及使用。
由于 HashMap 的干扰,很多人认为 ConcurrentHashMap 是可以置入 null 值,而事实上, 存储 null 值时会抛出 NPE 异常
Map 类集合 K/V 能不能存储 null 值的情况,如下表格:
| 集合类 | Key | Value | Super | 说明 |
|---|---|---|---|---|
| Hashtable | 不允许为 null | 不允许为 null | Dictionary | 线程安全 |
| ConcurrentHashMap | 不允许为 null | 不允许为 null | AbstractMap | 分段锁技术 |
| TreeMap | 不允许为 null | 允许为 null | AbstractMap | 线程不安全 |
| HashMap | 允许为 null | 允许为 null | AbstractMap | 线程不安全 |
常见的NullPointerException总结的更多相关文章
- Core Java 总结(异常类问题)
所有代码均在本地编译运行测试,环境为 Windows7 32位机器 + eclipse Mars.2 Release (4.5.2) 2016-10-17 整理 下面的代码输出结果是多少?为什么?并由 ...
- Java异常处理和设计
在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常处理,当程序出错从哪里寻 ...
- Java中的异常-Throwable-Error-Exception-RuntimeExcetpion-throw-throws-try catch
今天在做一个将String转换为Integer的功能时,发现Integer.parseInte()会抛出异常NumberFormatException. 函数Integer.parseInt(Stri ...
- Java异常处理和设计【转】
Java异常处理和设计 在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常 ...
- java 异常处理 Throwable Error 和Exception
Java异常类层次结构图: 异常的英文单词是exception,字面翻译就是“意外.例外”的意思,也就是非正常情况.事实上,异常本质上是程序上的错误,包括程序逻辑错误和系统错误. 比如使用 ...
- Java中异常处理和设计
在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常处理,当程序出错从哪里寻 ...
- 201521123038 《Java程序设计》 第九周学习总结
201521123038 <Java程序设计> 第九周学习总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 ...
- 关于一些基础的Java问题的解答(三)
11. HashMap和ConcurrentHashMap的区别 从JDK1.2起,就有了HashMap,正如上一个问题所提到的,HashMap与HashTable不同,不是线程安全的,因此多线程 ...
- Android开发过程中的坑及解决方法收录(三)
bug:应用出现了 不幸运的,应用已停止的错误提示 排除问题: 1.intent接收数据的字符串不匹配 2.java常见的NullPointerException(空指针错误),可能由三个原因引起,字 ...
随机推荐
- MSF魔鬼训练营-3.1.2信息收集-通过搜索引擎进行信息搜集
1.Google hacking 技术 自动化的Google搜索工具 SiteDigger https://www.mcafee.com/us/downloads/free-tools/sitedig ...
- spring boot-14.集成MyBatis
1.如何使用注解版Mybatis? (1)引入mybatis ,druid,Mysql 的依赖,环境搭建可以参考第13篇的内容 <dependency> <groupId>or ...
- Java -cp命令的使用
服务器跑程序,用到了一些Linux命令,做个简单笔记. Linux(Mac)下 java -cp .:jar包路径 主类的全限定名称 全限定名有绝对路径的意思,比如一个文件file的存放路径, ...
- Java四类八项基本数据类型
一. 四类八项基本数据类型 1. 整数类型(byte.short.int.long) 三点注意事项: a. Java各整数类型有固定的表示范围和字段长度,其不收操作系统的影响,以保持Java的可移植性 ...
- Luogu P2915 [USACO08NOV]奶牛混合起来
题外话: 是非常颓废的博主 写题解也不在于能不能通过啦,主要是缓解颓废 首先看到这个题,肯定是可以暴力搜索的: 不得不说这道题还是很善良的,一波大暴力dfs,居然有70pts: #include< ...
- Comet OJ - Contest #13
Rank53. 第一次打这种比赛.还是有不少问题的,以后改吧. A题WA了两次罚了不少时. C写到一半发现只能过1,就先弃了. D一眼没看出来.第二眼看出来就是一个类似于复数的快速幂. 然后B切了. ...
- HNUST-1047 二叉树的表示
1047: 二叉树的表示 时间限制: 1 Sec 内存限制: 128 MB提交: 4 解决: 4[提交][状态][讨论版] 题目描述 DJ非常痴迷于数据结构,二叉树是他最喜欢的结构模型.这种每个 ...
- 编辑器IDE之VSCode
很多时候面临换项目组,公司内部换等等,需要清除之前的权限,电脑更换等... 确实很烦人,所以记录也是给自己下次更加快速方便的使用 插件安装 个人常用的一些插件,发现好用的会更新 插件名 功能 vsco ...
- 带EFI支持的GRUB2安装全记录
版权归作者所有,任何形式转载请联系作者. 作者:keenshoes(来自豆瓣) 来源:https://www.douban.com/note/210077866/ 关键词:EFIGRUB2efibo ...
- Vue的双向数据绑定的原理
Vue数据双向绑定的原理就是采用数据劫持结合发布者-订阅者模式,通过object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监 ...