第二次执行while(rs.next())时触发java.lang.NullPointerException求助
排查Java ResultSet第二次循环空指针异常的问题
嗨,我来帮你搞定这个困扰你的空指针问题!先拆解你代码里的核心问题,咱们一步步解决:
核心问题1:Statement复用导致外层ResultSet被强制关闭
你在第一个while(rs.next())循环里,复用了同一个stmt对象执行内部查询stmt.executeQuery("*Select Query*")——这里有个容易踩的坑:同一个Statement对象执行新查询时,它之前关联的ResultSet会被自动关闭!
第一次循环结束后,外层的rs已经失效关闭了,第二次调用rs.next()时,自然会触发空指针(本质是ResultSet已无法使用)。
核心问题2:ResultSet指针操作不严谨的潜在风险
你操作rs_second时用了rs_second.previous(),如果当前指针已经在第一行,previous()会返回false,此时指针不在任何有效数据行上,再调用rs_second.getString()直接就会抛出空指针异常。
修复方案
1. 为内部查询创建独立的Statement对象
别复用外层的stmt,每次内部查询都新建一个Statement(或用PreparedStatement更安全高效),这样就不会影响外层的ResultSet。
2. 优化ResultSet指针操作逻辑
避免随意来回移动指针,直接在rs_second.next()的有效范围内获取数据,完全不需要用previous()绕弯子。
修复后的代码示例
String[] Starttime = new String[5000]; String[] Endtime = new String[5000]; int st = 0; int et = 0; // 外层循环遍历原ResultSet while (rs.next()) { // 新建独立的Statement执行内部查询,避免干扰外层rs Statement innerStmt = conn.createStatement(); // conn是你的数据库连接对象 ResultSet rs_second = innerStmt.executeQuery("*你的Select Query*"); while (rs_second.next()) { if (/* 你的判断条件 */) { // 直接获取当前行数据,无需移动指针 Endtime[et] = rs_second.getString("rec_datetime"); et++; } else if (/* 另一个判断条件 */) { Starttime[st] = rs_second.getString("rec_datetime"); st++; } } // 及时关闭内部资源,避免泄漏 rs_second.close(); innerStmt.close(); System.out.println(); System.out.println(st); System.out.println(et); } // 后续的日期处理循环逻辑...
额外优化建议
- 优先用
PreparedStatement替代Statement,尤其是查询带参数时,能防SQL注入还能提升重复执行的性能。 - 用try-with-resources语法自动管理数据库资源,不用手动写close:
try (Statement innerStmt = conn.createStatement(); ResultSet rs_second = innerStmt.executeQuery("*你的Select Query*")) { // 操作rs_second的逻辑写在这里 } // 代码块结束后会自动关闭innerStmt和rs_second - 固定长度的数组(5000)容易触发数组越界,建议换成
ArrayList<String>,动态扩容更安全灵活。
内容的提问来源于stack exchange,提问作者Aman Malhotra
相关产品推荐
相关产品推荐

