- Что такое NullPointerException и как это исправить
- NullPointerException – что это такое?
- Как исправить NullPointerException
- Как избегать исключения NullPointerException
- Проверяйте на null все объекты, которые создаются не вами
- Не верьте входящим данным
- Возвращайте существующие объекты, а не null
- Заключение
- Java NullPointerException — Detect, Fix, and Best Practices
- java.lang.NullPointerException
- Java NullPointerException Examples
- 1. NullPointerException when calling an instance method
- 2. Java NullPointerException while accessing/modifying field of a null object
- 3. Java NullPointerException when null is passed in method argument
- 4. java.lang.NullPointerException when null is thrown
- 5. NullPointerException when getting the length of null array
- 6. NullPointerException when accessing index value of null array
- 7. NullPointerException when synchronized on a null object
- 8. HTTP Status 500 java.lang.NullPointerException
- How to detect java.lang.NullPointerException
- How to fix NullPointerException
- Coding Best Practices to avoid NullPointerException
Что такое NullPointerException и как это исправить
Довольно часто при разработке на Java программисты сталкиваются с NullPointerException, появляющимся в самых неожиданных местах. В этой статье мы разберёмся, как это исправить и как стараться избегать появления NPE в будущем.
NullPointerException – что это такое?
NullPointerException (оно же NPE) это исключение, которое выбрасывается каждый раз, когда вы обращаетесь к методу или полю объекта по ссылке, которая равна null. Разберём простой пример:
Integer n1 = null; System.out.println(n1.toString());
Здесь на первой строке мы объявили переменную типа Integer и присвоили ей значение null (то есть переменная не указывает ни на какой существующий объект).
На второй строке мы обращаемся к методу toString переменной n1. Так как переменная равна null, метод не может выполниться (переменная не указывает ни на какой реальный объект), генерируется исключение NullPointerException:
Exception in thread "main" java.lang.NullPointerException at ru.javalessons.errors.NPEExample.main(NPEExample.java:6)
Как исправить NullPointerException
В нашем простейшем примере мы можем исправить NPE, присвоив переменной n1 какой-либо объект (то есть не null):
Integer n1 = 16; System.out.println(n1.toString());
Теперь не будет исключения при доступе к методу toString и наша программа отработает корректно.
Если ваша программа упала из-за исключение NullPointerException (или вы перехватили его где-либо), вам нужно определить по стектрейсу, какая строка исходного кода стала причиной появления этого исключения. Иногда причина локализуется и исправляется очень быстро, в нетривиальных случаях вам нужно определять, где ранее по коду присваивается значение null.
Иногда вам требуется использовать отладку и пошагово проходить программу, чтобы определить источник NPE.
Как избегать исключения NullPointerException
Существует множество техник и инструментов для того, чтобы избегать появления NullPointerException. Рассмотрим наиболее популярные из них.
Проверяйте на null все объекты, которые создаются не вами
Если объект создаётся не вами, иногда его стоит проверять на null, чтобы избегать ситуаций с NullPinterException. Здесь главное определить для себя рамки, в которых объект считается «корректным» и ещё «некорректным» (то есть невалидированным).
Не верьте входящим данным
Если вы получаете на вход данные из чужого источника (ответ из какого-то внешнего сервиса, чтение из файла, ввод данных пользователем), не верьте этим данным. Этот принцип применяется более широко, чем просто выявление ошибок NPE, но выявлять NPE на этом этапе можно и нужно. Проверяйте объекты на null. В более широком смысле проверяйте данные на корректность, и консистентность.
Возвращайте существующие объекты, а не null
Если вы создаёте метод, который возвращает коллекцию объектов – не возвращайте null, возвращайте пустую коллекцию. Если вы возвращаете один объект – иногда удобно пользоваться классом Optional (появился в Java 8).
Заключение
В этой статье мы рассказали, как исправлять ситуации с NullPointerException и как эффективно предотвращать такие ситуации при разработке программ.
Java NullPointerException — Detect, Fix, and Best Practices
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
java.lang.NullPointerException is one of the most popular exceptions in java programming. Anybody working in java must have seen this popping out of nowhere in the java standalone program as well as the java web application.
java.lang.NullPointerException
NullPointerException is a runtime exception, so we don’t need to catch it in the program. NullPointerException is raised in an application when we are trying to do some operation on null where an object is required. Some of the common reasons for NullPointerException in java programs are:
- Invoking a method on an object instance but at runtime the object is null.
- Accessing variables of an object instance that is null at runtime.
- Throwing null in the program
- Accessing index or modifying value of an index of an array that is null
- Checking the length of an array that is null at runtime.
Java NullPointerException Examples
Let’s look at some examples of NullPointerException in java programs.
1. NullPointerException when calling an instance method
public class Temp public static void main(String[] args) Temp t = initT(); t.foo("Hi"); > private static Temp initT() return null; > public void foo(String s) System.out.println(s.toLowerCase()); > >
When we run the above program, it throws the following NullPointerException error message.
Exception in thread "main" java.lang.NullPointerException at Temp.main(Temp.java:7)
We are getting NullPointerException in the statement t.foo(«Hi»); because “t” is null here.
2. Java NullPointerException while accessing/modifying field of a null object
public class Temp public int x = 10; public static void main(String[] args) Temp t = initT(); int i = t.x; > private static Temp initT() return null; > >
The above program throws the following NullPointerException stack trace.
Exception in thread "main" java.lang.NullPointerException at Temp.main(Temp.java:9)
NullPointerException is being thrown in statement int i = t.x; because “t” is null here.
3. Java NullPointerException when null is passed in method argument
public class Temp public static void main(String[] args) foo(null); > public static void foo(String s) System.out.println(s.toLowerCase()); > >
This is one of the most common occurrences of java.lang.NullPointerException because it’s the caller who is passing the null argument.
The below image shows the null pointer exception when the above program is executed in Eclipse IDE.
4. java.lang.NullPointerException when null is thrown
public class Temp public static void main(String[] args) throw null; > >
Below is the exception stack trace of the above program, showing NullPointerException because of throw null; statement.
Exception in thread "main" java.lang.NullPointerException at Temp.main(Temp.java:5)
5. NullPointerException when getting the length of null array
public class Temp public static void main(String[] args) int[] data = null; int len = data.length; > >
Exception in thread "main" java.lang.NullPointerException at Temp.main(Temp.java:7)
6. NullPointerException when accessing index value of null array
public class Temp public static void main(String[] args) int[] data = null; int len = data[2]; > >
Exception in thread "main" java.lang.NullPointerException at Temp.main(Temp.java:7)
7. NullPointerException when synchronized on a null object
public class Temp public static String mutex = null; public static void main(String[] args) synchronized(mutex) System.out.println("synchronized block"); > > >
The synchronized(mutex) will throw NullPointerException because the “mutex” object is null.
8. HTTP Status 500 java.lang.NullPointerException
Sometimes we get an error page response from a java web application with an error message as “HTTP Status 500 – Internal Server Error” and root cause as java.lang.NullPointerException .
For this, I edited the Spring MVC Example project and changed the HomeController method as below.
@RequestMapping(value = "/user", method = RequestMethod.POST) public String user(@Validated User user, Model model) System.out.println("User Page Requested"); System.out.println("User Name: "+user.getUserName().toLowerCase()); System.out.println("User ID: "+user.getUserId().toLowerCase()); model.addAttribute("userName", user.getUserName()); return "user"; >
The below image shows the error message thrown by the web application response.
Here is the exception stack trace:
HTTP Status 500 – Internal Server Error Type Exception Report Message Request processing failed; nested exception is java.lang.NullPointerException Description The server encountered an unexpected condition that prevented it from fulfilling the request. Exception org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982) org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) javax.servlet.http.HttpServlet.service(HttpServlet.java:661) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) javax.servlet.http.HttpServlet.service(HttpServlet.java:742) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) Root Cause java.lang.NullPointerException com.journaldev.spring.controller.HomeController.user(HomeController.java:38) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:498)
The root cause is NullPointerException in the statement user.getUserId().toLowerCase() because user.getUserId() is returning null.
How to detect java.lang.NullPointerException
Detecting NullPointerException is very easy, just look at the exception trace and it will show you the class name and line number of the exception. Then look at the code and see what could be null causing the NullPointerException. Just look at all the above examples, it’s very clear from stack trace what is causing null pointer exception.
How to fix NullPointerException
java.lang.NullPointerException is an unchecked exception, so we don’t have to catch it. The null pointer exceptions can be prevented using null checks and preventive coding techniques. Look at below code examples showing how to avoid java.lang.NullPointerException .
if(mutex ==null) mutex =""; //preventive coding synchronized(mutex) System.out.println("synchronized block"); >
//using null checks if(user!=null && user.getUserName() !=null) System.out.println("User Name: "+user.getUserName().toLowerCase()); > if(user!=null && user.getUserName() !=null) System.out.println("User ID: "+user.getUserId().toLowerCase()); >
Coding Best Practices to avoid NullPointerException
1. Let’s consider the below function and look out for scenario causing null pointer exception.
public void foo(String s) if(s.equals("Test")) System.out.println("test"); > >
The NullPointerException can occur if the argument is being passed as null. The same method can be written as below to avoid NullPointerException.
public void foo(String s) if ("Test".equals(s)) System.out.println("test"); > >
2. We can also add null check for argument and throw IllegalArgumentException if required.
public int getArrayLength(Object[] array) if(array == null) throw new IllegalArgumentException("array is null"); return array.length; >
3. We can use ternary operator as shown in the below example code.
String msg = (str == null) ? "" : str.substring(0, str.length()-1);
4. Use String.valueOf() rather than toString() method. For example check PrintStream println() method code is defined as below.
public void println(Object x) String s = String.valueOf(x); synchronized (this) print(s); newLine(); > >
The below code snippet shows the example where the valueOf() method is used instead of toString().
Object mutex = null; //prints null System.out.println(String.valueOf(mutex)); //will throw java.lang.NullPointerException System.out.println(mutex.toString());
5. Write methods returning empty objects rather than null wherever possible, for example, empty list, empty string, etc.
6. There are some methods defined in collection classes to avoid NullPointerException, you should use them. For example contains(), containsKey(), and containsValue().
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.