Integer(null) 拆箱后与 int(0) 比较报空指针异常

本文探讨了Java中Integer对象与int基本类型进行比较时可能遇到的问题,特别是当Integer对象为null时会发生空指针异常的情况。文章给出了两种避免此类异常的方法,并强调了在进行类型转换时对null值进行检查的重要性。

Integer(null)拆箱后与int比较报空指针异常

首先代码是这样的:


	Integer i = 0;
	Integer Obj = null;
	
	if(0 == Obj  || null == Obj ){...}

这样,当Obj 值为null 时,那个if语句会报错,为什么呢?

当 Obj 为null时,证明 Obj是没有值,是未赋值状态;
而 i 是有值,只是它的值是 0 。

在Obj 取值的时候是null值,可是按说明来说基本类型和包装类型都是可以通过自动拆箱和自动装箱自由转换的,为什么null值没有被转换为0么?

在这里插入图片描述
源码:
在这里插入图片描述
在这里插入图片描述

所以当 判断 0 == obj,会报空指针异常。所以在获取到值有可能为空要装箱的时候,一定要加上null值的校验,将代码写成如下的格式就不会有错误了。

	int res = (Obj == null ? 0 : obj)

或者代码最上面的代码改为:


	Integer i = 0;
	Integer Obj = null;
	
	if( null == Obj || 0 == Obj ){...}

感谢浏览~~~

参考:

Java-Integer与Int类型的比较-装箱与拆箱详解
int 和 Integer
包装类型拆箱的时候null值会自动转换吗?

如果你明确指出是 **`rankListPo` 空指针异常NullPointerException)**,那说明在执行如下代码时: ```java GetHeroRankListPo rankListPo = new GetHeroRankListPo(); BeanUtils.copyProperties(rankListPo, pos); ``` 虽然你创建了 `rankListPo`,理论上不会为 `null`,但 **异常是发生在 `BeanUtils.copyProperties(rankListPo, pos);` 这一行**,说明异常 **不是因为 `rankListPo` 本身为 null**,而是: > **在拷贝过程中访问了 `rankListPo` 的某个字段或方法时,该字段或方法内部使用了 null 对象。** --- ## ✅ 一、为什么会说 `rankListPo` 空指针? 这通常意味着: ### ❗1. `rankListPo` 中的某个字段为 `null`,并且在 `BeanUtils.copyProperties` 拷贝过程中调用了它的方法。 例如: ```java public class GetHeroRankListPo { private Double winRate; public void setWinRate(Double winRate) { this.winRate = winRate; } public Double getWinRate() { return winRate; } } ``` 如果 `BeanUtils.copyProperties` 在赋值时试图调用类似: ```java Double winRate = source.getWinRate(); // source 可能为 null dest.setWinRate(winRate); ``` 如果 `source.getWinRate()` 返回 `null`,而 `dest.setWinRate()` 接受的是 `double`(基本类型)而不是 `Double`(包装类型),就可能导致自动拆箱时抛出 `NullPointerException`。 --- ## ✅ 二、典型错误场景:基本类型 vs 包装类型不匹配 假设你有两个类: ```java class Source { private Double winRate; public Double getWinRate() { return winRate; } } class Target { private double winRate; public void setWinRate(double winRate) { this.winRate = winRate; } } ``` 当你执行: ```java BeanUtils.copyProperties(target, source); ``` 如果 `source.winRate == null`,那么在调用 `target.setWinRate(source.getWinRate())` 时,Java 会尝试将 `null` 自动拆箱为 `double`,导致: > `java.lang.NullPointerException` 这就是典型的 **自动拆箱导致的空指针异常**。 --- ## ✅ 三、解决方案 ### ✅ 1. 使用包装类型(Double、Integer 等)代替基本类型(double、int) ```java public class GetHeroRankListPo { private Double winRate; // ✅ 使用包装类型 public void setWinRate(Double winRate) { this.winRate = winRate; } public Double getWinRate() { return winRate; } } ``` 这样即使 `null` 也不会抛出异常。 --- ### ✅ 2. 检查字段类型是否一致 确保源类目标类中字段的类型完全一致,比如: - `Double` ↔ `Double` - `String` ↔ `String` - `LocalDate` ↔ `LocalDate` 不要混用 `double` `Double`、`int` `Integer` 等。 --- ### ✅ 3. 使用日志或调试定位具体字段 你可以打印出 `pos` 的内容,查看是否有字段为 `null`: ```java .map(pos -> { System.out.println("Processing pos: " + pos); // 打印对象,查看字段是否为 null GetHeroRankListPo rankListPo = new GetHeroRankListPo(); BeanUtils.copyProperties(rankListPo, pos); return rankListPo; }) ``` --- ### ✅ 4. 使用 try-catch 捕获并打印详细信息(用于调试) ```java .map(pos -> { GetHeroRankListPo rankListPo = new GetHeroRankListPo(); try { BeanUtils.copyProperties(rankListPo, pos); } catch (Exception e) { e.printStackTrace(); System.out.println("Error while copying from: " + pos); } return rankListPo; }) ``` --- ## ✅ 四、推荐代码(安全写法) ```java List<GetHeroRankListPo> rankListPos = heroRankList.stream() .filter(Objects::nonNull) .map(pos -> { GetHeroRankListPo rankListPo = new GetHeroRankListPo(); try { org.springframework.beans.BeanUtils.copyProperties(rankListPo, pos); } catch (Exception e) { System.err.println("Error copying properties from: " + pos); e.printStackTrace(); } return rankListPo; }) .filter(Objects::nonNull) .collect(Collectors.toList()); ``` --- ## ✅ 五、总结 | 问题 | 原因 | 解决方案 | |------|------|----------| | `rankListPo` NPE | 实际是字段自动拆箱导致 | 使用包装类型(如 `Double`) | | 源对象字段为 null | 导致赋值时拆箱异常 | 检查字段类型是否一致 | | BeanUtils.copyProperties 不安全 | 自动拆箱问题 | 使用 Spring 版本,加 try-catch | --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值