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;
CodePudding user response:
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.)