What is a Null Pointer Exception (java.lang.NullPointerException
) and why might it happen?
What methods and tools to use to determine the cause of this exception, leading to the premature termination of the application?
Translation of the question “What is a Null Pointer Exception, and how do I fix it? ” @Ziggy .
Answer 1, authority 100%
When you declare a variable of a reference type, you are actually creating a reference to an object of that type. Consider the following code to declare a variable of type int:
int x;
x = 10;
In this example, the variable x
is of type int
and Java initializes it to 0. When you set the variable to 10 (second line), this value is stored in memory location, referenced by x
.
But when you declare a reference type, the process looks different. Let’s look at the following code:
Integer num;
num = new Integer (10);
The first line declares the variable num
, its type is not built-in, therefore, the value is a reference (the type of this variable, Integer
, is a reference type). Since you haven’t specified what you are going to refer to yet, Java will set the variable to Null
, implying “I’m not referencing anything.”
In the second line, the new
keyword is used to create an object of type Integer
. This object has an address in memory, which is assigned to the variable num
. Now, with the variable num
, you can refer to the object using the dereference operator .
.
The exception you are talking about in the question is thrown if you declared a variable but did not create an object, that is, if you try to dereference num
before you created object, you will get a NullPointerException
. In the simplest case, the compiler will detect the problem and report that
num
may not have been initialized
Which says, “the variable num
may not have been initialized.”
Sometimes the exception is caused precisely by the fact that the object has not really been created. For example, you might have the following function:
public void doSomething (Integer num) {
// Working with num
}
In this case, the creation of the object (the num
variable) lies with the calling code, that is, you assume that it was created earlier – before the call to the doSomething
method. Unfortunately, the following method call is quite possible:
doSomething (null);
In this case, the value of the variable num
will be null
. The best way to avoid this exception is to test for equality to zero. As a result, the doSomething
function must be rewritten as follows:
public void doSomething (Integer num) {
if (num! = null) {
// Working with num
}
}
As an alternative to the previous example, you can tell the caller that the method was called with invalid parameters, for example, using IllegalArgumentException
.
public void doSomething (Integer num) {
if (num == null)
throw new IllegalArgumentException ("Num must not be null");
// Working with num
}
Also, pay attention to the question “What is stack trace and how can I use it to find errors in application development? “.
Translation of the answer “What is a Null Pointer Exception, and how do I fix it? ” @Vincent Ramdhanie .
Answer 2, authority 14%
Optional
has been added to java8 to prevent NullPointerException
, although it may not always be used correctly. Here is a link with recommendations on how to use Optional
Typical solution with checking for null
Article article = getFirstJavaArticle ();
if (article == null) {
article = fetchLatestArticle ();
}
And now the solution using Optional & lt; T & gt;
. Imagine getFirstJavaArticle ()
returns Optional & lt; Article & gt;
getFirstJavaArticle ()
.orElseGet (this :: fetchLatestArticle);
The Optional
solution allows us to avoid code with null
checks and work in a functional style. It is worth noting that Optional is not a panacea for all ills
The pattern is also used to prevent
NullPointerException
NullObject
Abstract Entity class
public abstract class AbstractCustomer {
protected String name;
public abstract String getName ();
}
Real implementation
public class RealCustomer extends AbstractCustomer {
public RealCustomer (String name) {
this.name = name;
}
@Override
public String getName () {
return name;
}
}
Implementation of NullObject
public class NullCustomer extends AbstractCustomer {
@Override
public String getName () {
return "Not Available in Customer Database";
}
}
Usage (as an example)
public class CustomerFactory {
public static final String [] names = {"Rob", "Joe", "Julie"};
public static AbstractCustomer getCustomer (String name) {
for (int i = 0; i & lt; names.length; i ++) {
if (names [i] .equalsIgnoreCase (name)) {
return new RealCustomer (name);
}
}
return new NullCustomer ();
}
}
Instead of returning null
, we return an instance of the NullCustomer
class and don’t fall out with a NullPointerException
. But it seems to me that there is a small Overhead: it is necessary to create an inheritance hierarchy.
Answer 3
I advise you to use Optional
to prevent NPE. This class was introduced in java 8.
For example
@Entity
public class Car {
@Id
@GeneratedValue
private Long id;
@Column (name = "name")
@NotNull
private String name;
}
Repository:
public interface CarRepository extends JpaRepository & lt; Car, Long & gt; {
Optional & lt; Car & gt; findById (Long id);
}
Service:
@ Service
public class CarService {
private CarRepository carRepository;
@Autowired
public CarService (CarRepository carRepository) {
this.carRepository = carRepository;
}
public Car findById (Long id) {
Car car = carRepository.findById (id) .orElseThrow (() - & gt;
new RuntimeException ("Requested entity was not found"));
car.getHolder (). setPassword (null);
return car;
}
}
Controller:
@ RestController
@RequestMapping ("/ api")
public class CarController {
private CarService carService;
@Autowired
public CarController (CarService carService) {
this.carService = carService;
}
@RequestMapping (value = "/ cars / {id}", method = RequestMethod.GET)
public ResponseEntity & lt; Car & gt; getCar (@PathVariable Long id) {
try {
Car carToFind = carService.findById (id);
return ResponseEntity.status (HttpStatus.OK) .body (carToFind);
} catch (Exception ex) {
return ResponseEntity.status (HttpStatus.BAD_REQUEST) .build ();
}
}
}
In this case, if the repository cannot find the machine, it will not throw out NPE.
Optional
helps you avoid null
checks and make your code shorter and more readable.
Answer 4
This is an Exception that occurs when you refer to an object that = null (not initialized) or try to call methods / access variables of an object that = null. Solution to this problem:
-
Checking for null,
if (Your object == null) {// Your code}
-
try {} catch (NullPointerException e) {// Your code}
-
When a null is thrown to you, it usually indicates a “hierarchy of lines” (what, how it was called, what brought you to null). And there you can see where your object is not initialized, and there you can immediately correct the error.
-
May occur in arrays / lists when you call object n, even though the object has not been previously written there.
Like, everything))