Today I will show you simple techniques on how to avoid NullPointerException in your applications. They are easy to follow, but significantly improve the reliability and quality of your code. Moreover, in my experience, the first tip will have a noticeable impact on the quality of your code. If you know any other Java programming tricks, feel free to share them in the comments.
Use
There are many open source libraries that take on the heavy burden of testing for Try not to return
This is another good Java programming tip that Joshua Bloch describes in his book Java: Effective Programming. When returning empty collections or arrays, make sure that calling base methods like
Call equals() and equalsIgnoreCase() methods on a known string literal rather than an unknown object
Always call a methodequals()
on a known string that you know is not null
. The method equals()
is symmetric, that is, calling a.equals(b)
and b.equals(a)
will give the same result (if a
and b
not null
), and for this reason many programmers do not pay attention to which objects are called equals()
, y a
or y b
. One of the side effects of this is a NullPointerException if the method is called on null
.
Object unknownObject = null;
//плохой способ - может вызвать NullPointerException
if(unknownObject.equals("knownObject")){
System.err.println("This may result in NullPointerException if unknownObject is null");
}
//правильный способ - исключение NullPointerException не возникнет, даже если unknownObject null
if("knownObject".equals(unknownObject)){
System.err.println("better coding avoided NullPointerException");
}
This was the simplest tip for avoiding NullPointerException, but it alone makes a huge improvement because the method equals()
is ubiquitous.
Choose valueOf() over toString() in cases where both produce the same result
Since callingtoString()
on a reference with a value null
throws a NullPointerException, it's better to use calling valueOf()
when we can get the same result, since calling valueOf()
from null
returns null
. This is especially true for wrapper classes such as Integer
, Float
, Double
or BigDecimal
.
BigDecimal bd = getPrice();
System.out.println(String.valueOf(bd)); //не выбрасывает NPE
System.out.println(bd.toString()); //выбрасывает "Exception in thread "main" java.lang.NullPointerException"
Use these tips when you are not sure whether an object can exist null
or not.
Use null
-safe methods and libraries
There are many open source libraries that take on the heavy burden of testing for null
. One of the most common is StringUtils
from Apache Commons. Using methods such as StringUtils.isBlank()
, isNumeric()
, isWhiteSpace()
etc. you don't have to worry about throwing a NullPointerException.
//Методы StringUtils являются null-безопасными, они не вызовут NullPointerException
System.out.println(StringUtils.isEmpty(null));
System.out.println(StringUtils.isBlank(null));
System.out.println(StringUtils.isNumeric(null));
System.out.println(StringUtils.isAllUpperCase(null));
Output: true true false false And yet, before using, do not forget to read the documentation null
of safe methods and classes. This is another one of the best Java tricks that leads to huge improvements without requiring much effort.
Try not to return null
from a method, it is better to return an empty collection
This is another good Java programming tip that Joshua Bloch describes in his book Java: Effective Programming. When returning empty collections or arrays, make sure that calling base methods like size()
or length()
does not throw a NullPointerException. The class Collections
specifically declares convenient implementations of empty lists, sets and dictionaries: Collections.EMPTY_LIST
, Collections.EMPTY_SET
and Collections.EMPTY_MAP
. For example:
public List getOrders(Customer customer){
List result = Collections.EMPTY_LIST;
return result;
}
Similarly, you can use Collections.EMPTY_SET
it Collections.EMPTY_MAP
instead of returning null
.
Use @NotNull and @Nullable annotations
In the description of your methods, you can definenull
method safety conventions using annotations @NotNull
and @Nullable to indicate whether a method can return null
or not. Modern compilers and IDEs can use these annotations to analyze your code and give appropriate advice, for example, about missing a check for null
, or vice versa, about the possibility of removing an unnecessary check that is clogging up the code. Such annotations, for example, are supported by the IntelliJ IDE and FindBugs, and they are also included in JSR 305. But even if your IDE does not support such annotations, they will be good documentation in themselves. Looking at @NotNull
and @Nullable
it will be easier for the programmer to understand where to add a check for null
and where not. This, by the way, is a fairly new practice among Java programmers, and it will take time for it to spread.
Avoid unnecessary autoboxing and autounboxing in your code
Not only does this lead to the creation of unnecessary temporary objects, but autoboxing can also throw a NullPointerException if the wrapper class isnull
. For example, the following code will throw a NullPointerException if the person entry does not contain a phone number and returns null
.
Person ram = new Person("ram");
int phone = ram.getPhone();
When using autoboxing or autounboxing, not only equalities, but also inequalities <
> >
can result in a NullPointerException.
Follow conventions and define reasonable defaults.
One of the best ways to avoid NullPointerException in Java is to properly declare and follow coding conventions. Most NullPointerExceptions occur when you try to create an object without having all the data and dependencies it requires. By preventing the creation of unfinished objects by gracefully rejecting such requests, you will save yourself from a large number of NullPointerExceptions in the future. Likewise, if you allow object creation, you should choose a reasonable default value. For example, a class objectEmployee
cannot be created without a name and id
, but may not have a phone number. In this case, objects Employee
without a number may return zero instead null
. Although such behavior of the object should be thought through in advance - it may be easier to check for null
than to call a non-existent number. In this case, having additional conditions on which fields are null
and which are not will help make the right decision. In general, the choice between immediately crashing the program or assigning null
it is an important design decision, and once you have made the choice, you must follow it consistently.
Set restrictions at the DBMS level
When using a database to store your program objects, such as Customers or Orders, it is wise to specify the "null
ness" of your objects at the DBMS level, using appropriate table restrictions. Databases often contain information from multiple sources, and introducing checks for missing values will improve the integrity of your data. In addition, the presence of checks for null at the DBMS level will reduce them in your Java code: by loading data from the database into Java objects, you can be sure of their presence and remove unnecessary " != null
" from the program code.
Use the Null Object Pattern
Creating specialNull
-objects is another way to avoid NullPointerExcpetion in Java. Let's assume that some method in our application returns an object that the program subsequently works with by calling its methods. For example, the method Collection.iterator()
returns an object of the class Iterator
that is used to iterate through the collection. Then if the original object does not have any iterator, null
you can instead return a special Null
-object that has a method hasNext()
that always returns false
. That's all, dear reader, this is where I end my tips for ridding Java programs of NullPointerException errors. You will appreciate how useful these simple and not burdensome rules can be. As a reminder, if you want to share any other NullPointerException tricks in Java programs, feel free to do so in the comments. Translated specifically for JavaRush students. Original
GO TO FULL VERSION