In this article, we will talk about the infamous NullPointerException Java Error and how to solve it.
1. What is Null in Java?
The null
is a keyword and it means that an object’s address points to nothing. Moreover, all objects in Java are null by default unless we initialize them. Finally, a primitive can never have null
value, therefore, a variable of type int, short, byte, long, double, float, boolean
will always have some value.
String x; // It is null Object o; // It is null Integer y; // It is null boolean z; // It is false int a; //It is 0
2. What is Null Pointer Exception in Java and How It Is Caused
The NullPointerException in Java is a runtime exception and it is thrown when any of the following happens:
- We call an instance method of an object that is null
- We access or modify a null field of an object
- We throw a Null Pointer Exception using
throw
keyword
Furthermore, a NullPointerException will be thrown if we take the length of an array, or access or modify a slot even though the array is null.
Before we begin, consider that we have declared the following class:
public class Company { private String ticker; //Map that holds the annual revenue, e.g. 2020 -> 10_000_000, 2021 -> 12_000_000 private Map<Integer, Double> annualRevenueMap; private Map<LocalDate, Double> closingStockPrice; public String getTicker() { return ticker; } public void setTicker(String ticker) { this.ticker = ticker; } public Map<Integer, Double> getAnnualRevenueMap() { return annualRevenueMap; } public void setAnnualRevenueMap(Map<Integer, Double> annualRevenueMap) { this.annualRevenueMap = annualRevenueMap; } public Map<LocalDate, Double> getClosingStockPrice() { return closingStockPrice; } public void setClosingStockPrice(Map<LocalDate, Double> closingStockPrice) { this.closingStockPrice = closingStockPrice; } }
2.1 Cause NullPointerException by Calling a Method of a Null Object
The most common way that Null Pointer Exception is caused, is by calling a method of a null object.
Now consider the following:
Company company = null; try { String ticker = company.getTicker(); } catch (NullPointerException npe) { System.out.println("You tried to call the method getTicker() of a null object"); } company = new Company(); try { company.getAnnualRevenueMap().put(2020, 10_000_000d); } catch (NullPointerException npe) { System.out.println("You tried to call the method put() of a null object"); }
Firstly, we create a new company object that is null and we call the getTicker() method since the company is null
, we will get a NullPointerException.
Secondly, we create a new company object by using the new keyword. Note that when we declared the class we did not initialize any fields and as a result, the status of a newly created object will be this:
Company[ticker=null, annualRevenueMap=null, closingStockPrice = null]
With this in mind, if we call company.getAnnualRevenueMap().put(2020, 10_000_000d);
we try to put an entry into a null map and we get a null pointer exception since this could never happen.
Consequently, we can remedy this by changing the class as follows:
private Map<Integer, Double> annualRevenueMap = new HashMap<>(); private Map<LocalDate, Double> closingStockPrice = new HashMap<>();
2.2 Cause NullPointerException by Accessing or Modifying the Field Of a Null Object
In the same fashion, another way Null Pointer Exception is caused is by modifying a field of a null object:
Company company = null; try { String ticker = company .ticker; } catch (NullPointerException npe) { System.out.println("You tried to access a field of a null object"); } try { company.ticker = "AAPL"; } catch (NullPointerException npe) { System.out.println("You tried to modify a field of a null object"); }
In the first try-catch block, we just accessed the ticker field of a null company object, and therefore we got the Null Pointer Exception.
In the second block, we tried to set the ticker to AAPL and again, NullPointerException was there.
2.3 Throw Null Pointer Exception
Of course, the simplest way to cause NullPointerException is to throw it:
try { throw new NullPointerException("Throwing NPE for fun"); } catch (NullPointerException nullPointerException) { System.out.println("Why would you do that?"); }
2.4 NullPointerException with Java Array
Last but not least, a NullPointerException can also be thrown when dealing with arrays:
String[][] x = new String[2][2]; x = null; try { System.out.println(x.length); } catch (NullPointerException npe) { System.out.println("We accessed the length of null"); } try { System.out.println(x[0][0]); } catch (NullPointerException npe) { System.out.println("We accessed the slot of null"); } try { x[0][0] = "Hello"; } catch (NullPointerException npe) { System.out.println("We modified the slot of null"); }
Of course, the above will print:
We accessed the length of null We accessed the slot of null We modified the slot of null
3. How to Handle Null Pointer Exception in Java
Provided that we now know how NullPointerException is caused, it’s time to see how we can handle it
Consider that we are requesting some information from an API, such as a company’s information and this API might fail sometimes and return nothing or return some of the information and not all:
CompanyInfo tesla = APIClient.get("Tesla")
The CompanyInfo
returns much more information than we need, and we want to convert this object to the Company object shown below:
public class Company { private String ticker; private double closingPriceToday; private double priceToEarningsRatio; public String getTicker() { return ticker; } public void setTicker(String ticker) { this.ticker = ticker; } public double getClosingPriceToday() { return closingPriceToday; } public void setClosingPriceToday(double closingPriceToday) { this.closingPriceToday = closingPriceToday; } public double getPriceToEarningsRatio() { return priceToEarningsRatio; } public void setPriceToEarningsRatio(double priceToEarningsRatio) { this.priceToEarningsRatio = priceToEarningsRatio; } }
3.1 How to Avoid Null Pointer Exception in Java with If Statement
CompanyInfo companyInfo = APIClient.get("Tesla"); Company company = new Company(); if(companyInfo != null) { company.setTicker(companyInfo.getTicker()); company.setClosingPriceToday(companyInfo.getClosingPriceToday()); company.setPriceToEarningsRatio(companyInfo.getPriceToEarningsRatio()); } else { System.out.println("API failed"); }
In this example, in case the API returns a null object, we just check if the object returned is null in order to avoid NullPointerException when calling the getters.
3.2 How to Avoid Null Pointer Exception with Java 8 Optional
Alternatively, and with the addition of Java 8 Optional class, you can use a far more readable and elegant way to perform the same null checks:
CompanyInfo companyInfo = APIClient.get("Tesla"); Company company = new Company(); Optional.ofNullable(companyInfo).ifPresent(ci -> { company.setTicker(ci.getTicker()); company.setClosingPriceToday(ci.getClosingPriceToday()); company.setPriceToEarningsRatio(ci.getPriceToEarningsRatio()); });
Note that if the object returned had fields that could be null, e.g:
companyInfo.getAnnualRevenueMap()
As a final point, you would also need to check if this field is null before you call any method of it:
Optional.ofNullable(companyInfo).ifPresent(ci -> { company.setTicker(ci.getTicker()); company.setClosingPriceToday(ci.getClosingPriceToday()); company.setPriceToEarningsRatio(ci.getPriceToEarningsRatio()); //Checking for another field double twentyTwentyRevenue = Optional .ofNullable(ci.getAnnualRevenueMap()) .map(map -> map.get(2020)) .orElse(-1); });
Should you like to learn everything about Optionals, I suggest that you read Java 8 Optional article.
3.3 How to Catch Null Pointer Exception in Java
All things considered, you can even let the exceptions happen and catch them using a try-catch block:
CompanyInfo companyInfo = APIClient.get("Tesla"); Company company = new Company(); try { company.setTicker(companyInfo.getTicker()); company.setPriceToEarningsRatio(companyInfo.getPriceToEarningsRatio()); company.setClosingPriceToday(companyInfo.getClosingPriceToday()); } catch (NullPointerException e) {}
In the above example, if the companyInfo
is null, the first line will throw a NullPointerException and it will be caught in the catch block.
Important note: Letting exceptions be thrown is not suggested as in order for the exception to find all the required information for the stack trace, it needs to go through the call stack, which can affect performance.
4. Conclusion
By now you should know what causes the dreaded NullPointerException and how to avoid it effectively either by using if statements or by taking advantage of the Optional Class.