Java新手求助:使用Scanner读取CSV创建Product数组时抛出异常
嘿,刚接触Java遇到这种问题太正常啦,别担心!我来帮你捋捋可能的问题和解决办法~
首先先明确你的场景:你要从Name,Price,Stock格式的CSV里读数据,创建Product数组,但调用Load()时在构造函数行报错,结合你给出的代码片段,大概率是这几个常见问题导致的:
可能的错误原因
- 分隔符没设置正确:Scanner默认用空白符(空格、换行)做分隔符,但CSV是用逗号分隔字段的。如果没设置正确的分隔符,会把整行内容当成一个字符串,传给Product构造函数时必然类型不匹配。
- 字段类型没转换:Price是数字(double)、Stock是整数(int),如果直接把读取到的字符串传给构造函数的数值类型参数,会抛出
NumberFormatException。 - 构造函数参数不匹配:你的Product构造函数参数顺序、类型,和你读取字段的顺序、类型不一致,比如构造函数是
Product(String name, int stock, double price),但你按name→price→stock传参,就会报错。 - CSV格式异常:如果CSV里有空行、某一行字段数量不对,读取时会拿到不足的参数,调用构造函数时参数数量不够。
修正后的示例代码
我给你写了一个完整的、带异常处理的版本,你可以参考:
import java.io.File; import java.io.FileNotFoundException; import java.util.Arrays; import java.util.Scanner; public class ProductLoader { private Product[] products = new Product[100]; // 变量名用复数更贴合数组含义 // Java方法名推荐小驼峰命名哦 public Product[] load() throws FileNotFoundException { int counter = 0; // 用try-with-resources自动关闭Scanner,避免资源泄漏 try (Scanner scanner = new Scanner(new File("products.csv"))) { // 设置分隔符:匹配逗号或者换行符,确保正确拆分每个字段和每行数据 scanner.useDelimiter(",|\n"); while (scanner.hasNext()) { try { // 读取字段时去掉前后可能的空格,避免解析数字出错 String name = scanner.next().trim(); double price = Double.parseDouble(scanner.next().trim()); int stock = Integer.parseInt(scanner.next().trim()); // 这里要确保和你的Product构造函数参数完全匹配 products[counter] = new Product(name, price, stock); counter++; } catch (NumberFormatException e) { // 遇到格式错误的行,打印提示并跳过,防止程序崩溃 System.out.println("跳过格式错误的数据行:" + e.getMessage()); scanner.nextLine(); // 跳过当前行剩余内容,不影响下一行读取 } catch (IllegalArgumentException e) { // 如果构造函数有参数校验,比如价格不能为负,这里可以捕获处理 System.out.println("参数不符合要求:" + e.getMessage()); scanner.nextLine(); } } } // 返回实际有数据的数组(去掉多余的空位置),可选但更实用 return Arrays.copyOf(products, counter); } } // 你的Product类需要有对应的构造函数 class Product { private String name; private double price; private int stock; // 构造函数参数顺序、类型要和读取时一致 public Product(String name, double price, int stock) { // 可以加一些参数校验,比如价格不能为负,库存不能为负 if (price < 0) { throw new IllegalArgumentException("价格不能为负数"); } if (stock < 0) { throw new IllegalArgumentException("库存不能为负数"); } this.name = name; this.price = price; this.stock = stock; } // 可选:添加getter/setter方法 public String getName() { return name; } public double getPrice() { return price; } public int getStock() { return stock; } }
额外注意事项
- 文件路径:确保
products.csv放在项目的根目录下(如果是IDE的话,就是和src同级的目录),如果不在,要写完整路径,比如new File("src/main/resources/products.csv")。 - 命名规范:Java里方法名、变量名用小驼峰,类名用大驼峰,这样代码更易读。
- 资源关闭:用try-with-resources语法处理Scanner,不用手动调用
close(),JVM会自动释放资源。
内容的提问来源于stack exchange,提问作者mzanaty
相关产品推荐
相关产品推荐

