初始化StringBuilder数组遇NullPointerException:两种循环写法差异解析
为什么增强for循环初始化StringBuilder数组会抛出NullPointerException?
你遇到的问题核心在于增强for循环(foreach)和普通for循环操作数组元素的本质差异,咱们拆开说清楚:
先看报错的写法到底出了啥问题
StringBuilder[] sb = new StringBuilder[2]; for(StringBuilder s : sb){ s = new StringBuilder(); } System.out.println(sb[0].toString());
当你创建new StringBuilder[2]时,数组里的每个元素默认都是null——引用类型数组初始化时,会自动填充空引用。
这里的增强for循环,本质是把数组里的每个元素(也就是null)赋值给了临时变量s。你执行s = new StringBuilder(),只是让这个临时变量指向了新创建的对象,但完全没修改原数组里的元素!原数组的两个位置依然是null,调用sb[0].toString()自然会触发空指针异常。
再看正常工作的写法为啥没问题
StringBuilder[] sb = new StringBuilder[2]; for(int i = 0; i < 2; i++) { sb[i] = new StringBuilder(); } System.out.println(sb[0].toString());
普通for循环是通过下标sb[i]直接定位到数组的具体内存位置,然后把新创建的StringBuilder对象直接赋值给数组的对应元素。这样数组里的每个位置都被正确初始化,后续调用自然不会报错。
两者的关键差异总结
- 增强for循环:遍历数组时是把元素值拷贝给临时变量,对临时变量的修改不会影响原数组本身。
- 普通for循环:通过下标直接操作数组的内存位置,修改的是数组元素的实际引用。
打个比方:就像你有两个空抽屉(数组元素),增强for循环是把“抽屉是空的”这个状态告诉一个临时便签,然后你给便签贴了个新抽屉的标签,但原来的空抽屉还是空的;而普通for循环是直接给原来的空抽屉里放了新东西,自然就能正常使用了。
内容的提问来源于stack exchange,提问作者Garatee
相关产品推荐
相关产品推荐

