java.lang.NullPointerException:使用try/catch创建列表时的格式化程序

java.lang.NullPointerException: formatter when using try/catch to create a list

我有一个 CustomerRepository class:

public class CustomerRepository {

    private static final String FILE_PATH = "src/poly/customer/data.txt";

    public List<AbstractCustomer> customers;

    {
        try {
            customers = readFiles();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");

    public List<AbstractCustomer> readFiles() throws IOException{
        List<AbstractCustomer> result = new ArrayList<>();
        List<String> lines = Files.readAllLines(Path.of(FILE_PATH));
        for (String line : lines) {
            String[] parts = line.split(";");
            int points = Integer.parseInt(parts[3]);
            LocalDate date = LocalDate.parse(parts[4], formatter);
            if (parts[0].equals("REGULAR")) {
                RegularCustomer customer = new RegularCustomer(parts[1], parts[2], points, date);
                result.add(customer);
            } else if (parts[0].equals("GOLD")) {
                GoldCustomer customer = new GoldCustomer(parts[1], parts[2], points);
                result.add(customer);
            } else {
                throw new IOException();
            }
        }
        return result;
    }

我想从文件中读取客户,然后将他们添加到客户列表中。我试着这样做:

{
        try {
            customers = readFiles();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

这给了我 java.lang.NullPointerException:格式化程序,我该如何解决这个问题?此方法应从文本文件创建对象,然后将它们添加到客户列表中。我的文本文件如下所示:

常规;c1;爱丽丝;0;2022-03-10

常规;c2;鲍勃;0;2022-01-04

黄金;c3;卡罗尔;0;

问题是您的实例初始化程序(带有 tr/catch 语句的块)在 formatter 的字段初始化程序之前执行,因此 formatter 仍然为空。

how can I fix this?

可以 只需将 formatter 的声明(包括初始化)移动到实例初始化程序上方......但我建议通过以下方式使代码更易于理解使用构造函数来初始化 customers 而不是实例初始化程序块。

我还建议将 formatter 设置为 static 字段 - DateTimeFormatter 是不可变的并且 thread-safe 无论如何,你正在存储它在最后一个字段中,那么为什么要为每个实例创建一个新字段呢? (这本身就可以解决问题,但为了可读性,我仍然建议使用普通的构造函数声明。)