Java数组初始化后调用方法触发NullPointerException问题排查
排查Java数组初始化的NullPointerException问题
嘿,我来帮你解决这个空指针的问题!咱们先拆解一下你代码里的问题根源,再给出修复方案。
问题出在哪?
你遇到的java.lang.NullPointerException,核心原因是后置自增运算符index++的执行时机和你预期的不一样:
- 循环统计非null元素后,
index的值是8(因为你初始化了索引0到7的8个元素)。 - 执行
passengers[index++] = new Passenger();时,Java会先使用index当前的值(8)来赋值,也就是把新的Passenger对象放到passengers[8],然后再把index加1变成9。 - 接下来你调用
passengers[index].enterDetails();,此时index是9,但passengers[9]还没有被初始化(还是null),自然就触发了空指针异常。
而你直接写passengers[8] = new Passenger();后调用方法正常,是因为你明确访问的是已经初始化好的passengers[8],没有碰未初始化的索引9。
修复方案
这里有两种简单的修复方式,根据你的需求选就行:
方案1:先初始化再调用方法,分开处理自增
如果只需要初始化一个剩余元素,把代码改成这样:
public class Demo { public static void main(String[] args) { Passenger[] passengers = new Passenger[10]; passengers[0] = new Passenger("Mr", "Benjamin", "Parker"); passengers[1] = new Passenger(....); passengers[2] = new Passenger(....); passengers[3] = new Passenger(....); passengers[4] = new Passenger(....); passengers[5] = new Passenger(....); passengers[6] = new Passenger(....); passengers[7] = new Passenger(....); int index = 0; for (int i = 0; i < passengers.length; i++) { if (passengers[i] != null) index++; } // 先初始化当前index位置的元素 passengers[index] = new Passenger(); // 调用这个元素的方法 passengers[index].enterDetails(); // 如果之后还要继续初始化,再自增index index++; } }
方案2:循环初始化所有剩余元素
如果要把剩下的2个元素都初始化,可以用循环来处理,更简洁:
public class Demo { public static void main(String[] args) { Passenger[] passengers = new Passenger[10]; passengers[0] = new Passenger("Mr", "Benjamin", "Parker"); passengers[1] = new Passenger(....); passengers[2] = new Passenger(....); passengers[3] = new Passenger(....); passengers[4] = new Passenger(....); passengers[5] = new Passenger(....); passengers[6] = new Passenger(....); passengers[7] = new Passenger(....); int index = 0; // 先找到第一个null的位置 while (index < passengers.length && passengers[index] != null) { index++; } // 初始化所有剩余的null元素 while (index < passengers.length) { passengers[index] = new Passenger(); passengers[index].enterDetails(); index++; } } }
关键提醒
记住:后置自增variable++是先使用变量当前的值,再把变量加1;如果是前置自增++variable,则是先加1再使用值。这次的问题就是因为没注意这个细节,导致访问了未初始化的数组位置。
内容的提问来源于stack exchange,提问作者papert1ger
相关产品推荐
相关产品推荐

