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

I have a 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;
    }

I want to read customers from the file, and then add them to the customers List. I tried to do it like this :

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

This gives me java.lang.NullPointerException: formatter, how can I fix this? This method should create objects from the text file and then add them to the customers list. My text file looks like this:

REGULAR;c1;Alice;0;2022-03-10

REGULAR;c2;Bob;0;2022-01-04

GOLD;c3;Carol;0;

>Solution :

The problem is that your instance initializer (the block with the tr/catch statement) executes before the field initializer for formatter, so formatter is still null.

how can I fix this?

You could just move the declaration (including the initialization) of formatter above the instance initializer… but I would suggest making the code simpler to understand by using a constructor to initialize customers instead of the instance initializer block.

I’d also recommend making formatter a static field – DateTimeFormatter is immutable and thread-safe anyway, you’re storing it in a final field, so why create a new one for each instance? (That would fix the problem in itself, but I’d still suggest using a normal constructor declaration for the sake of readability.)

Leave a Reply