Java中的空指针异常
NullPointerException是一个 RuntimeException。在Java中,可以为对象引用分配一个特殊的 null 值。当程序尝试使用具有 null 值的对象引用时,将引发 NullPointerException。
这些可以是:
- 从空对象调用方法。
- 访问或修改空对象的字段。
- 取null的长度,就好像它是一个数组一样。
- 访问或修改空对象的槽,就像它是一个数组一样。
- 抛出 null,就好像它是一个 Throwable 值。
- 当您尝试通过空对象进行同步时。
为什么我们需要空值?
Null 是Java中使用的特殊值。主要用于表示没有给引用变量赋值。 null 的一种应用是实现链表和树等数据结构。其他应用包括 Null Object 模式(详情请参阅此)和 Singleton 模式。单例模式确保只创建一个类的实例,并且旨在提供对对象的全局访问点。
最多创建一个类的一个实例的示例方法是将其所有构造函数声明为私有,然后创建一个返回该类的唯一实例的公共方法:
Java
// To use randomUUID function.
import java.util.UUID;
import java.io.*;
class Singleton
{
// Initializing values of single and ID to null.
private static Singleton single = null;
private String ID = null;
private Singleton()
{
/* Make it private, in order to prevent the
creation of new instances of the Singleton
class. */
// Create a random ID
ID = UUID.randomUUID().toString();
}
public static Singleton getInstance()
{
if (single == null)
single = new Singleton();
return single;
}
public String getID()
{
return this.ID;
}
}
// Driver Code
public class TestSingleton
{
public static void main(String[] args)
{
Singleton s = Singleton.getInstance();
System.out.println(s.getID());
}
}
Java
// A Java program to demonstrate that invoking a method
// on null causes NullPointerException
import java.io.*;
class GFG
{
public static void main (String[] args)
{
// Initializing String variable with null value
String ptr = null;
// Checking if ptr.equals null or works fine.
try
{
// This line of code throws NullPointerException
// because ptr is null
if (ptr.equals("gfg"))
System.out.print("Same");
else
System.out.print("Not Same");
}
catch(NullPointerException e)
{
System.out.print("NullPointerException Caught");
}
}
}
Java
// A Java program to demonstrate that we can avoid
// NullPointerException
import java.io.*;
class GFG
{
public static void main (String[] args)
{
// Initializing String variable with null value
String ptr = null;
// Checking if ptr is null using try catch.
try
{
if ("gfg".equals(ptr))
System.out.print("Same");
else
System.out.print("Not Same");
}
catch(NullPointerException e)
{
System.out.print("Caught NullPointerException");
}
}
}
Java
// A Java program to demonstrate that we should
// check if parameters are null or not before
// using them.
import java.io.*;
class GFG
{
public static void main (String[] args)
{
// String s set an empty string and calling getLength()
String s = "";
try
{
System.out.println(getLength(s));
}
catch(IllegalArgumentException e)
{
System.out.println("IllegalArgumentException caught");
}
// String s set to a value and calling getLength()
s = "GeeksforGeeks";
try
{
System.out.println(getLength(s));
}
catch(IllegalArgumentException e)
{
System.out.println("IllegalArgumentException caught");
}
// Setting s as null and calling getLength()
s = null;
try
{
System.out.println(getLength(s));
}
catch(IllegalArgumentException e)
{
System.out.println("IllegalArgumentException caught");
}
}
// Function to return length of string s. It throws
// IllegalArgumentException if s is null.
public static int getLength(String s)
{
if (s == null)
throw new IllegalArgumentException("The argument cannot be null");
return s.length();
}
}
Java
// A Java program to demonstrate that we can use
// ternary operator to avoid NullPointerException.
import java.io.*;
class GFG
{
public static void main (String[] args)
{
// Initializing String variable with null value
String str = null;
String message = (str == null) ? "" :
str.substring(0,5);
System.out.println(message);
// Initializing String variable with null value
str = "Geeksforgeeks";
message = (str == null) ? "" : str.substring(0,5);
System.out.println(message);
}
}
输出:
10099197-8c2d-4638-9371-e88c820a9af2
在上面的示例中,单例类的静态实例。该实例最多在 Singleton getInstance 方法中初始化一次。
如何避免 NullPointerException?
为避免 NullPointerException,我们必须确保所有对象都已正确初始化,然后再使用它们。当我们声明一个引用变量时,我们必须在从对象请求方法或字段之前验证对象不为空。
以下是解决该问题的解决方案的常见问题。
案例 1:字符串与字面量的比较
一个非常常见的案例问题涉及字符串变量和字面量之间的比较。字面量可以是字符串或枚举的元素。不要从 null 对象调用方法,而是考虑从字面量量调用它。
Java
// A Java program to demonstrate that invoking a method
// on null causes NullPointerException
import java.io.*;
class GFG
{
public static void main (String[] args)
{
// Initializing String variable with null value
String ptr = null;
// Checking if ptr.equals null or works fine.
try
{
// This line of code throws NullPointerException
// because ptr is null
if (ptr.equals("gfg"))
System.out.print("Same");
else
System.out.print("Not Same");
}
catch(NullPointerException e)
{
System.out.print("NullPointerException Caught");
}
}
}
输出:
NullPointerException Caught
我们可以通过在字面量而不是对象上调用 equals 来避免 NullPointerException。
Java
// A Java program to demonstrate that we can avoid
// NullPointerException
import java.io.*;
class GFG
{
public static void main (String[] args)
{
// Initializing String variable with null value
String ptr = null;
// Checking if ptr is null using try catch.
try
{
if ("gfg".equals(ptr))
System.out.print("Same");
else
System.out.print("Not Same");
}
catch(NullPointerException e)
{
System.out.print("Caught NullPointerException");
}
}
}
输出:
Not Same
案例 2:检查方法的参数
在执行新方法的主体之前,我们应该首先检查它的参数是否为空值,然后继续执行该方法,只有在正确检查了参数的情况下。否则,它将抛出IllegalArgumentException并通知调用方法传递的参数有问题。
Java
// A Java program to demonstrate that we should
// check if parameters are null or not before
// using them.
import java.io.*;
class GFG
{
public static void main (String[] args)
{
// String s set an empty string and calling getLength()
String s = "";
try
{
System.out.println(getLength(s));
}
catch(IllegalArgumentException e)
{
System.out.println("IllegalArgumentException caught");
}
// String s set to a value and calling getLength()
s = "GeeksforGeeks";
try
{
System.out.println(getLength(s));
}
catch(IllegalArgumentException e)
{
System.out.println("IllegalArgumentException caught");
}
// Setting s as null and calling getLength()
s = null;
try
{
System.out.println(getLength(s));
}
catch(IllegalArgumentException e)
{
System.out.println("IllegalArgumentException caught");
}
}
// Function to return length of string s. It throws
// IllegalArgumentException if s is null.
public static int getLength(String s)
{
if (s == null)
throw new IllegalArgumentException("The argument cannot be null");
return s.length();
}
}
输出:
0
13
IllegalArgumentException caught
案例 3:使用三元运算符
三元运算符可用于避免 NullPointerException。首先,计算布尔表达式。如果表达式为真,则返回 value1,否则返回 value2。我们可以使用三元运算符来处理空指针:
Java
// A Java program to demonstrate that we can use
// ternary operator to avoid NullPointerException.
import java.io.*;
class GFG
{
public static void main (String[] args)
{
// Initializing String variable with null value
String str = null;
String message = (str == null) ? "" :
str.substring(0,5);
System.out.println(message);
// Initializing String variable with null value
str = "Geeksforgeeks";
message = (str == null) ? "" : str.substring(0,5);
System.out.println(message);
}
}
输出:
Geeks