解析非空字符串触发java.lang.NumberFormatException: empty String问题求助
看起来你遇到的问题有点诡异——明明打印出来的tempArray[0]是合法的500.0,但调用Double.parseDouble()时却抛出空字符串的异常。结合你的代码和输出,我来帮你分析几个最可能的原因和解决办法:
1. 文件开头存在UTF-8 BOM(字节顺序标记)
这是Windows系统下保存UTF-8文件时常见的坑:文件开头会自动添加一个隐藏的BOM字符(\uFEFF),这个字符在控制台打印时不会显示,但会导致tempArray[0]实际是"\uFEFF500.0"。虽然肉眼看是正常字符串,但Double.parseDouble()无法识别开头的BOM,可能会抛出异常(部分场景下会被误判为空字符串)。
解决办法:
在读取每一行后,先检查并移除BOM:
temp = sc.nextLine(); // 移除UTF-8 BOM(如果存在) if (temp.startsWith("\uFEFF")) { temp = temp.substring(1); } tempArray = temp.split(" % ");
2. 文件中存在空行或空白字符
虽然你提供的文件内容看起来正常,但实际文件可能在第一行前有空白行,或者某行内容只有空白字符。当sc.nextLine()读取到空行时,temp.split(" % ")会得到一个包含空字符串的数组,此时tempArray[0]就是空,直接触发异常。
解决办法:
在处理每行前先trim并跳过空行:
temp = sc.nextLine().trim(); // 跳过空行 if (temp.isEmpty()) { continue; } tempArray = temp.split(" % ");
3. 分隔符不匹配
你代码中用的分隔符是" % "(空格+百分号+空格),但如果文件中的分隔符实际是"%"(无空格)、全角空格或其他变体,split()后的数组结构会混乱,可能导致tempArray[0]包含多余内容,甚至在某些情况下为空。
验证方法:
打印tempArray的长度,确认每行都被拆分成了5个元素:
System.out.println("数组长度:" + tempArray.length);
如果长度不是5,说明分隔符不匹配,需要调整split()的参数。
4. 调试隐藏字符
如果以上方法都没解决,建议打印tempArray[0]的详细信息,查看是否有不可见字符:
System.out.println("待解析字符串:" + tempArray[0]); System.out.println("字符串长度:" + tempArray[0].length()); // 打印每个字符的ASCII码 for (char c : tempArray[0].toCharArray()) { System.out.println("字符:'" + c + "',ASCII码:" + (int) c); }
这样可以直观看到是否有隐藏的空白字符、BOM或其他异常字符。
修复后的完整示例代码
结合上述处理,你的测试代码可以修改为:
import java.io.File; import java.io.IOException; import java.util.Scanner; public class test { public static void main(String[] args) throws IOException { File payChecks = new File("C:\\Users\\zwtw\\Documents\\paychecks.txt"); Scanner sc = new Scanner(payChecks); while (sc.hasNextLine()) { String temp = sc.nextLine().trim(); // 跳过空行 if (temp.isEmpty()) { continue; } // 移除UTF-8 BOM if (temp.startsWith("\uFEFF")) { temp = temp.substring(1); } String[] tempArray = temp.split(" % "); // 验证数组长度,避免索引越界 if (tempArray.length != 5) { System.out.println("无效行:" + temp); continue; } System.out.println(tempArray[0]); double payCheckAmount = Double.parseDouble(tempArray[0]); String paycheckDate = tempArray[1]; String description = tempArray[2]; boolean payCheckSplit = Boolean.parseBoolean(tempArray[3]); double amountUnSplit = Double.parseDouble(tempArray[4]); // 这里可以添加对象创建或其他逻辑 System.out.println("解析成功:" + payCheckAmount); } sc.close(); } }
内容的提问来源于stack exchange,提问作者Chase Geis

