java.lang.nullpointerexception.
在本教程中,我们将看到最常用的Java异常:nullpointerexception。
它是运行时异常之一。
nullpointerexception的原因
由Java文档定义的nullpointerexception的原因。
- 调用NULL对象的实例方法。
- 访问或者修改NULL对象的字段。
- 占用空长度,就像它是一个数组一样。
- 访问或者修改空插槽,就像它是数组一样。
- 扔空虚,好像它是一个扔的价值。
- 当我们添加NULL到不允许诸如ConcurrentHashMap等空的集合
- 尝试使用null对象同步。
让我们详细了解这些中的每一个。
我正在创建一个我们将在我们的例子中使用的员工程序。
package org.igi.theitroad;
public class Employee {
String name;
int age;
public Employee()
{
}
public Employee(String name, int age) {
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
1.调用NULL对象的实例方法
这是最明显的。
package org.igi.theitroad;
public class InvokingMethodOnNullMain {
public static void main(String[] args) {
Employee e1=null;
String name = e1.getName();
System.out.println("Employee Name: "+ name);
}
}
运行上面的程序时,我们将得到以下输出。
Exception in thread “main" java.lang.NullPointerException at org.igi.theitroad.comvokingMethodOnNullMain.main(InvokingMethodOnNullMain.java:7)
正如我们所见,E1在第7行是空,我们正在调用GetMethod,这就是为什么我们在这里获得NullPointerException。
2.访问或者修改NULL对象的字段。
与null上的调用实例方法非常相似。
package org.igi.theitroad;
public class NullFieldExampleMain {
public static void main(String[] args) {
Employee e1=null;
String name = e1.name;
System.out.println("Employee Name: "+ name);
}
}
运行上面的程序时,我们将得到以下输出。
Exception in thread “main" java.lang.NullPointerException at org.igi.theitroad.NullFieldExampleMain.main(InvokingMethodOnNullMain.java:8)
如我们所见,E1在第8行为空,我们正在访问E1的名称字段,这就是我们在此处获得NullPointerException的原因。
3.占用空长度,就像它是一个数组一样。
当我们尝试获取空闲数组的长度时,我们将获得nullpointerexception。
package org.igi.theitroad;
public class NullArrayLengthMain {
public static void main(String[] args) {
Employee[] arrEmp=null;
int length = arrEmp.length;
System.out.println("Length of array: "+length);
}
}
运行上面的程序时,我们将得到以下输出。
Exception in thread “main" java.lang.NullPointerException at org.igi.theitroad.NullArrayLengthMain.main(InvokingMethodOnNullMain.java:9)
4.访问或者修改空的插槽,就像它是数组一样。
当我们尝试访问或者修改Array.let的Helthem的Null Slot时。
package org.igi.theitroad;
public class InvokingMethodOnNullMain {
public static void main(String[] args) {
Employee[] arrEmp=null;
System.out.println(arrEmp[3]);
}
}
运行上面的程序时,我们将得到以下输出。
Exception in thread “main" java.lang.NullPointerException at org.igi.theitroad.comvokingMethodOnNullMain.main(InvokingMethodOnNullMain.java:8)
5.击中空值,好像它是一个可口值。
当你扔掉空调。
package org.igi.theitroad;
public class InvokingMethodOnNullMain {
public static void main(String[] args) {
throw null;
}
}
运行上面的程序时,我们将得到以下输出。
Exception in thread “main" java.lang.NullPointerException at org.igi.theitroad.comvokingMethodOnNullMain.main(InvokingMethodOnNullMain.java:7)
6.当我们将null添加到不允许unulls等null(如concurrenthashmap)
package org.igi.theitroad;
import java.util.concurrent.ConcurrentHashMap;
public class InvokingMethodOnNullMain {
public static void main(String[] args) {
ConcurrentHashMap<String, String> map=new ConcurrentHashMap<>();
map.put(null, "Dummy");
}
}
运行上面的程序时,我们将得到以下输出。
Exception in thread “main" java.lang.NullPointerException at java.base/java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1022) at java.base/java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1017) at org.igi.theitroad.comvokingMethodOnNullMain.main(InvokingMethodOnNullMain.java:10)
7.尝试使用NULL对象同步。
在NULL对象上同步时,我们将获得nullpointerexception
package org.igi.theitroad;
import java.util.concurrent.ConcurrentHashMap;
public class InvokingMethodOnNullMain {
public static void main(String[] args) {
Object obj=null;
synchronized (obj) {
ConcurrentHashMap<String, String> map=new ConcurrentHashMap<>();
map.put("Dummy", "value");
}
}
}
运行上面的程序时,我们将得到以下输出。
Exception in thread “main" java.lang.NullPointerException at org.igi.theitroad.comvokingMethodOnNullMain.main(InvokingMethodOnNullMain.java:10)
检测nullpointerexception.
更容易检测nullpointerexception。
检查异常跟踪,它会将类名称,方法名称和行Number.go告诉我们到该行号,检查nullpointerexception的原因。
修复nullpointerexception.
让我们带上方案并修复nullpointerexception。
1.零检查
在调用方法或者字段之前检查null。
package org.igi.theitroad;
public class InvokingMethodOnNullMain {
public static void main(String[] args) {
Employee e1=null;
if(e1!=null)
{
String name = e1.getName();
System.out.println("Employee Name: "+ name);
}
}
}
当我们运行上面的程序时,我们将无法获取nullpointerexcpetion。
2.在收集不允许空的集合中键或者值之前,请在键入键或者值之前检查
避免nullpointerexception的最佳实践
1.字符串比较
这是nullpointerexcpetion最常见的原因,让我们在举例的帮助下了解。
package org.igi.theitroad;
public class StringComparisonMain {
public static void main(String[] args) {
Employee e1=new Employee();
if(e1.getName().equalsIgnoreCase("John"))
{
System.out.println("Employee Name is John");
}
}
}
正如我们未设置员工E1的名称,我们将在此处获取NullPointerException。
运行上面的程序时,我们将得到以下输出。
Exception in thread “main" java.lang.NullPointerException at org.igi.theitroad.StringComparisonMain.main(StringComparisonMain.java:8)
我们可以更改如下逻辑。
package org.igi.theitroad;
public class StringComparisonMain {
public static void main(String[] args) {
Employee e1=new Employee();
if("John".equalsIgnoreCase(e1.getName()))
{
System.out.println("Employee Name is John");
}
}
}
这将避免nullpointerexception。
请注意,由于空缺,它可能会导致意外行为。
如果名称不能为员工零空缺,那么不要使用上述方法,因为它将在这种情况下忽略null名称。
2.使用可选
Java 8推出了一个名为可选的新类。
一般来说,我们在方法中找不到任何值,我们从中返回null,调用者检查null是否会恢复疼痛,以便检查null。
例如:
public static Employee findEmployee(List<Employee employeeList,String name)
{
for(Employee e:employeeList)
{
if(e.getName().equalsIgnoreCase(name))
{
return e;
}
}
return null;
}
正如我们所看到的,如果我们没有在雇员主义者中找到员工,我们将从FindeMployee方法返回NULL。
调用者将从FindeMployee方法获取员工对象,并且可以调用RetName()方法,该方法又可以升级NullPointerException.You可以使用可选避免此类情况。
package org.igi.theitroad;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class JavaOptionalMain {
public static void main(String[] args)
{
List<Employee> employeeList = createEmployeeList();
Optional<Employee> employeeOpt = findEmployee(employeeList,"John");
if(employeeOpt.isPresent())
{
Employee employee = employeeOpt.get();
System.out.println("Employee name: "+employee.getName());
}
else
{
System.out.println("There is no employee with name John");
}
}
public static Optional<Employee> findEmployee(List<Employee> employeeList,String name)
{
for(Employee e:employeeList)
{
if(e.getName().equalsIgnoreCase(name))
{
return Optional.of(e);
}
}
return Optional.empty();
}
public static List<Employee> createEmployeeList()
{
List<Employee> employeeList=new ArrayList<>();
Employee e1=new Employee("Adam",23);
Employee e2=new Employee("Dave",34);
Employee e3=new Employee("Carl",45);
Employee e4=new Employee("Mohan",29);
Employee e5=new Employee("Paresh",30);
employeeList.add(e1);
employeeList.add(e2);
employeeList.add(e3);
employeeList.add(e4);
employeeList.add(e5);
return employeeList;
}
}
There is no employee with name John
它会指示调用者而不是返回值可以为null。
3.使用Ternary Indertor
我们可以使用三元操作来检查null。
package org.igi.theitroad;
public class InvokingMethodOnNullMain {
public static void main(String[] args) {
Employee e1=null;
String name = e1==null?e1.getName():"";
System.out.println("Employee Name: "+ name);
}
}
正如我们所看到的,我们在此处不会得到nullpointerexception。
4. 始终检查方法的参数
package org.igi.theitroad;
public class InvokingMethodOnNullMain {
public static void main(String[] args) {
String str=null;
int len=getLength(str);
System.out.println("Length of String:"+ len);
}
public static int getLength(String str)
{
if(str!=null)
{
return str.length();
}
else
{
return 0;
}
}
}
5.使用apache常用的stricutils
我们可以使用StrictUtils类来处理大量字符串NULL和空字符串检查。
有时,我们需要检查字符串是否为空或者空,则可以使用strictutils的isempty方法来照顾它。

