Java中访问数组前需检查非空和索引范围,可用Optional封装安全获取;Python可用条件表达式实现类似safe_get函数。

Java 中访问数组前必须检查 arr != null && index >= 0 && index
很多人以为只要判断 index 就够了,但忽略数组引用本身可能是 null——这时触发的是 NullPointerException,不是 ArrayIndexOutOfBoundsException。尤其在多线程或懒加载场景下,这个空指针常被误判为“越界”,浪费大量排查时间。
- 错误写法:
if (i —— 若arr == null,直接 NPE - 正确写法:
if (arr != null && i >= 0 && i - 更简洁可读的替代:
Objects.nonNull(arr) && i >= 0 && i - 若逻辑允许,优先用增强 for 循环:
for (int x : arr),彻底绕开索引计算
Python 中用 len() 做前置校验比捕获 IndexError 更可靠
虽然 Python 支持 try/except IndexError,但频繁抛异常会拖慢性能,且掩盖真实逻辑缺陷。真正安全的做法是把边界检查变成访问前的显式条件。
- 访问后一个元素?别写
lst[i+1],改用:if i + 1 - 遍历配对操作(如每两个一组)?循环上限设为
len(lst) - 1,而不是len(lst):for i in range(0, len(lst) - 1, 2) - 反向索引虽支持负数,但
lst[-100]同样报IndexError,不能依赖“负数就安全”
Java 集合类如 List.get() 和字符串 String.charAt() 同样会越界
它们不叫 ArrayIndexOutOfBoundsException,但本质一样:StringIndexOutOfBoundsException 和 IndexOutOfBoundsException 都是其子类。JVM 内部常统一处理,开发者却容易掉以轻心。
-
str.charAt(i)前必须检查:i >= 0 && i -
list.get(i)前必须检查:i >= 0 && i - 更稳妥的兜底写法:
list.isEmpty() ? null : list.get(0),或封装成safeGet(list, i).orElse(null) - 避免
substring(0, str.length() + 1)这类明显越界的调用留在生产环境
别把防御逻辑写三遍:封装通用安全访问方法
每次手动写 if (arr != null && i >= 0 && i 容易漏、难维护。简单封装一次,后续复用成本几乎为零。
- Java 示例(泛型安全获取):
public static <t> Optional<t> safeGet(T[] arr, int index) { if (arr == null || index = arr.length) { return Optional.empty(); } return Optional.of(arr[index]); }</t></t> - 调用:
safeGet(myArray, 5).orElse("default") - Python 可用函数式写法:
def safe_get(lst, i, default=None): return lst[i] if 0 - 注意:工具方法不能替代设计——如果业务中大量出现“可能越界”的访问,该反思数据结构是否合理,而非只加防护
实际项目里最常出问题的,不是没写校验,而是校验位置不对:比如在循环体内部才检查 i+1,但循环变量 i 本身已超限;或者用了 ArrayList 却忘了它和数组一样有边界。越界从来不是“语言特性”,而是访问意图与数据现状不匹配的信号。










