java.lang.NullPointerException是最流行的Java程序(/社区/教程/例外处理-in-Java)编程之一.任何在Java工作的人都必须在Java独立程序以及JavaWeb应用程序(/社区/教程/javaweb-application-tutorial-for-beginners)中的任何地方都看到这种出现。
java.lang.NullPointer例外
NullPointerException是一个运行时间的例外,所以我们不需要在程序中捕捉它。NullPointerException在我们试图在 null上执行某些操作时在应用程序中提出。
- 在对象实例中调用方法,但在运行时对象为 null. 2.在运行时访问对象实例的变量为 null. 3.在程序中扔 null 4.访问指数或修改数组的指数值为 null 5.检查在运行时为 null的数组的长度
Java NullPointer例外
让我们来看看Java程序中的NullPointerException的几个例子。
1. NullPointerException 在调用实例方法时
1public class Temp {
2
3 public static void main(String[] args) {
4
5 Temp t = initT();
6
7 t.foo("Hi");
8
9 }
10
11 private static Temp initT() {
12 return null;
13 }
14
15 public void foo(String s) {
16 System.out.println(s.toLowerCase());
17 }
18}
当我们运行上述程序时,它会扔下面的 NullPointerException 错误消息。
1Exception in thread "main" java.lang.NullPointerException
2 at Temp.main(Temp.java:7)
我们在声明 t.foo(
Hi);
中得到 NullPointerException,因为t
在这里为 null。
2. Java NullPointerException 在访问/修改 null 对象的字段时
1public class Temp {
2
3 public int x = 10;
4
5 public static void main(String[] args) {
6
7 Temp t = initT();
8
9 int i = t.x;
10
11 }
12
13 private static Temp initT() {
14 return null;
15 }
16
17}
上面的程序会扔下面的 NullPointerException 堆栈痕迹。
1Exception in thread "main" java.lang.NullPointerException
2 at Temp.main(Temp.java:9)
NullPointerException 在声明中被扔到 int i = t.x;
,因为t
在这里为 null。
Java NullPointerException 当 null 在方法参数中被传递时
1public class Temp {
2
3 public static void main(String[] args) {
4
5 foo(null);
6
7 }
8
9 public static void foo(String s) {
10 System.out.println(s.toLowerCase());
11 }
12}
这是java.lang.NullPointerException
最常见的出现之一,因为它是通过 null 参数的召唤者。
下面的图像显示在 Eclipse IDE 中运行上述程序时的 null 指针例外。
4. java.lang.NullPointer 当 null 被扔掉时的例外
1public class Temp {
2
3 public static void main(String[] args) {
4
5 throw null;
6 }
7
8}
下面是上面的程序的例外堆栈跟踪,显示 NullPointerException 因为扔 null;
声明。
1Exception in thread "main" java.lang.NullPointerException
2 at Temp.main(Temp.java:5)
5. NullPointerException 在获取 null 数列的长度时
1public class Temp {
2
3 public static void main(String[] args) {
4
5 int[] data = null;
6
7 int len = data.length;
8 }
9
10}
1Exception in thread "main" java.lang.NullPointerException
2 at Temp.main(Temp.java:7)
访问 null 数组的索引值时的 NullPointerException
1public class Temp {
2
3 public static void main(String[] args) {
4
5 int[] data = null;
6
7 int len = data[2];
8 }
9
10}
1Exception in thread "main" java.lang.NullPointerException
2 at Temp.main(Temp.java:7)
7. NullPointerException 当同步到 null 对象时
1public class Temp {
2
3 public static String mutex = null;
4
5 public static void main(String[] args) {
6
7 synchronized(mutex) {
8 System.out.println("synchronized block");
9 }
10 }
11}
同步(mutex)
将丢弃NullPointerException,因为mutex
对象为null。
8. HTTP 状态 500 java.lang.NullPointerException
有时,我们会收到一个错误页面的响应(社区/教程/java-web-application-tutorial-for-beginners)与一个错误消息,如HTTP 状态 500 – 内部服务器错误
和根源原因为java.lang.NullPointerException
。
为此,我编辑了 [春季MVC示例]( / 社区 / 教程 / 春季MVC示例)项目,并如下所示更改了HomeController方法。
1@RequestMapping(value = "/user", method = RequestMethod.POST)
2 public String user(@Validated User user, Model model) {
3 System.out.println("User Page Requested");
4 System.out.println("User Name: "+user.getUserName().toLowerCase());
5 System.out.println("User ID: "+user.getUserId().toLowerCase());
6 model.addAttribute("userName", user.getUserName());
7 return "user";
8 }
下面的图像显示了 Web 应用程序响应投放的错误消息。
以下是例外 Stack Trace:
1HTTP Status 500 – Internal Server Error
2
3Type Exception Report
4
5Message Request processing failed; nested exception is java.lang.NullPointerException
6
7Description The server encountered an unexpected condition that prevented it from fulfilling the request.
8
9Exception
10
11org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
12 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
13 org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
14 javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
15 org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
16 javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
17 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
18Root Cause
19
20java.lang.NullPointerException
21 com.journaldev.spring.controller.HomeController.user(HomeController.java:38)
22 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
23 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
24 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
25 java.lang.reflect.Method.invoke(Method.java:498)
根源原因在声明 user.getUserId().toLowerCase()
中为 NullPointerException,因为 user.getUserId()
返回 null。
如何检测 java.lang.NullPointerException
检测 NullPointerException 非常简单,只需看看例外痕迹,它会向您显示例外的类名称和行号码。然后看看代码,看看什么可能导致 NullPointerException。
如何修复 NullPointerException
java.lang.NullPointerException是一个未经检查的例外,所以我们不必抓住它. null指针例外可以使用 null检查和预防性编码技术来防止。
1if(mutex ==null) mutex =""; //preventive coding
2
3synchronized(mutex) {
4 System.out.println("synchronized block");
5}
1//using null checks
2if(user!=null && user.getUserName() !=null) {
3System.out.println("User Name: "+user.getUserName().toLowerCase());
4}
5if(user!=null && user.getUserName() !=null) {
6 System.out.println("User ID: "+user.getUserId().toLowerCase());
7}
编码最佳实践以避免 NullPointerException
让我们考虑下面的函数,看看导致 null 指针例外的场景。
1public void foo(String s) {
2 if(s.equals("Test")) {
3 System.out.println("test");
4 }
5}
NullPointerException 可能会发生,如果参数被传递为 null. 可以写下面的相同方法来避免 NullPointerException。
1public void foo(String s) {
2 if ("Test".equals(s)) {
3 System.out.println("test");
4 }
5}
我们还可以为参数添加 null 检查,并在需要时扔IllegalArgumentException
。
1public int getArrayLength(Object[] array) {
2
3 if(array == null) throw new IllegalArgumentException("array is null");
4
5 return array.length;
6}
我们可以使用如下示例代码中所示的三级运算器。
1String msg = (str == null) ? "" : str.substring(0, str.length()-1);
使用String.valueOf()
而不是toString()
方法,例如检查 PrintStream println() 方法代码定义如下。
1public void println(Object x) {
2 String s = String.valueOf(x);
3 synchronized (this) {
4 print(s);
5 newLine();
6 }
7 }
下面的代码片段显示了使用 valueOf() 方法而不是 toString() 的示例。
1Object mutex = null;
2
3//prints null
4System.out.println(String.valueOf(mutex));
5
6//will throw java.lang.NullPointerException
7System.out.println(mutex.toString());
5、在可能的情况下,写出返回空对象而不是null的方法,例如空列表、空字符串等。
若要避免 NullPointerException,您应该使用某些方法,例如包含(),包含Key(),并包含Value()。
参考: API 文档