为什么 NULL 是你代码中的无声杀手?

为什么 NULL 是你代码中的无声杀手?

在软件开发领域,很少有问题像NULL值一样普遍存在且危害巨大。这个看似无害的占位符可能会给代码库带来重大问题,造成难以发现的漏洞,并损害数据完整性。尽管 NULL 有其用途,但处理不当且不了解其含义可能会导致严重问题。我们将在这篇详尽的博客文章中探讨 NULL 被称为代码中的无声杀手的原因,提供代码示例来展示其后果,并讨论减轻其负面影响的方法。

1. 简介NULL 是一个看似简单的概念,表示没有值。尽管 NULL 很简单,但它却因在软件应用程序中引起大量问题而臭名昭著。Tony Hoare 于 1965 年引入了 NULL 引用的概念,他经常将其称为“十亿美元的错误”。这篇文章旨在探讨 NULL 为何如此成问题,并为开发人员提供有效处理它的实用解决方案。

2. NULL 的概念NULL 是编程中用于表示变量没有值的特殊标记。它不同于零、空字符串或任何其他“假”值。NULL 的存在可能表示未初始化的变量、缺失的数据或可选字段。

NULL 的问题NULL 的根本问题是它的歧义性。它可能意味着:

值未知。值不存在。值不适用。这种模糊性可能会导致混乱和错误,尤其是在没有充分检查或处理 NULL 值时。

3. NULL 导致的常见问题空指针异常与 NULL 相关的最臭名昭著的问题之一是 NULL 指针异常 (NPE)。当程序尝试使用预期为对象但实际上为 NULL 的引用时,就会发生这种情况。在许多编程语言中,取消引用 NULL 指针会导致运行时错误,从而导致程序崩溃。

Java 示例:代码语言:javascript代码运行次数:0运行复制public class NullPointerExample {

public static void main(String[] args) {

String str = null;

try {

System.out.println(str.length());

} catch (NullPointerException e) {

System.out.println("Caught a NullPointerException");

}

}

}

数据不一致数据库中的 NULL 值可能会导致查询出现不一致和意外结果。例如,涉及 NULL 值的聚合和连接可能无法按预期运行。

SQL 示例:代码语言:javascript代码运行次数:0运行复制SELECT AVG(salary) FROM employees WHERE department_id = 10;

从员工中选择AVG (薪水) ,其中部门 ID = 10 ;如果某些工资值为空,则平均值计算可能会排除这些条目,从而导致结果偏差。

额外绩效开销处理 NULL 值通常需要在代码中进行额外的检查和分支,这会带来性能开销。这在性能至关重要的应用程序中尤其成问题,因为每微秒都至关重要。

4. 真实世界的代码示例Java 中的 NULLJava 开发人员经常遇到与 NULL 相关的问题,主要是 NULL 指针异常。Java 的类型系统允许将 NULL 分配给任何对象引用,这很容易引入错误。

例子:代码语言:javascript代码运行次数:0运行复制public class Employee {

private String name;

private Integer age;

public Employee(String name, Integer age) {

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public Integer getAge() {

return age;

}

}

public class NullExample {

public static void main(String[] args) {

Employee emp = new Employee(null, null);

try {

System.out.println(emp.getName().toUpperCase());

} catch (NullPointerException e) {

System.out.println("Caught a NullPointerException");

}

}

}

Python 中的 NULLPython 使用关键字处理 NULL 值None。虽然 Python 是动态类型的,这降低了一些风险,但如果处理不当,NULL 值仍然会导致运行时错误。

例子:代码语言:javascript代码运行次数:0运行复制def print_length(s):

try:

print(len(s))

except TypeError:

print("Caught a TypeError because the input was None")

print_length(None)

SQL 中的 NULLSQL 数据库使用 NULL 来表示缺失或未知值。但是,涉及 NULL 的运算可能会产生意外结果,尤其是在相等和聚合方面。

例子:代码语言:javascript代码运行次数:0运行复制SELECT * FROM employees WHERE manager_id = NULL; --不会返回任何 rows

SELECT * FROM employees WHERE manager_id IS NULL; -- 检查NULL的正确方法

5. 处理 NULL 的策略使用可选类型许多现代语言都提供可选或可空类型,以明确处理值的存在或不存在。这种方法鼓励开发人员考虑 NULL 的可能性并进行适当处理。

Java 示例(使用Optional):代码语言:javascript代码运行次数:0运行复制import java.util.Optional;

public class Employee {

private Optional name;

private Optional age;

public Employee(Optional name, Optional age) {

this.name = name;

this.age = age;

}

public Optional getName() {

return name;

}

public Optional getAge() {

return age;

}

}

public class OptionalExample {

public static void main(String[] args) {

Employee emp = new Employee(Optional.of("John Doe"), Optional.empty());

emp.getName().ifPresent(name -> System.out.println(name.toUpperCase()));

emp.getAge().ifPresentOrElse(

age -> System.out.println("Age: " + age),

() -> System.out.println("Age not available")

);

}

}

默认值和保护设置默认值并使用保护可以帮助避免与 NULL 相关的问题。这在配置和可选字段中特别有用。

Python 中的示例:代码语言:javascript代码运行次数:0运行复制def get_employee_name(employee):

return employee.get('name', 'Unknown')

employee = {}

print(get_employee_name(employee)) # Outputs 'Unknown'NULL 对象模式NULL 对象模式涉及创建一个表示默认行为的对象,而不是使用 NULL。这可以帮助避免 NULL 检查并使代码更具可读性。

Java 示例:代码语言:javascript代码运行次数:0运行复制public interface Employee {

String getName();

}

public class RealEmployee implements Employee {

private String name;

public RealEmployee(String name) {

this.name = name;

}

@Override

public String getName() {

return name;

}

}

public class NullEmployee implements Employee {

@Override

public String getName() {

return "No Name Available";

}

}

public class NullObjectPatternExample {

public static void main(String[] args) {

Employee emp = getEmployee(false);

System.out.println(emp.getName());

}

public static Employee getEmployee(boolean isReal) {

if (isReal) {

return new RealEmployee("John Doe");

} else {

return new NullEmployee();

}

}

}

数据库约束和默认值使用数据库约束和默认值可以防止将 NULL 插入不适当的字段。这确保了数据库级别的数据完整性。

SQL 示例:代码语言:javascript代码运行次数:0运行复制CREATE TABLE employees (

id INT PRIMARY KEY,

name VARCHAR(100) NOT NULL,

salary DECIMAL(10, 2) DEFAULT 0.00

);

INSERT INTO employees (id, name) VALUES (1, 'John Doe'); -- salary will default to 0.00

6.结论NULL 通常是代码中的隐形杀手,会导致微妙的错误、崩溃和数据不一致。通过了解它可能引起的问题并实施强大的策略来处理它,开发人员可以显著提高其应用程序的可靠性和可维护性。无论是通过使用可选类型、设置默认值、采用 NULL 对象模式还是强制执行数据库约束,都有许多方法可以减轻与 NULL 相关的风险。

采用这些最佳实践不仅有助于编写更安全、更可预测的代码,还可以提高软件系统的整体质量。请记住,解决问题的第一步是识别问题,对于任何旨在构建弹性和健壮应用程序的开发人员来说,承认 NULL 的潜在陷阱都至关重要。

🎯 相关推荐

周杰伦资产一共多少亿?
best365官网苹果下载

周杰伦资产一共多少亿?

📅 08-11 👁️ 4980
阿特兹与蒙迪欧究竟该如何抉择
best365官网苹果下载

阿特兹与蒙迪欧究竟该如何抉择

📅 08-11 👁️ 7605
[心得交流]真假鬼厉坐标谁知道?还有就上白虎给道具的任务为什么我一直没有?
普朗克踢脚线取暖器有什么特点?怎么判断优劣?
365bet真人体育

普朗克踢脚线取暖器有什么特点?怎么判断优劣?

📅 09-12 👁️ 464
为什么手机都是一体机
best365官网苹果下载

为什么手机都是一体机

📅 08-08 👁️ 5673
日肖是哪几个生肖,兔龙蛇马羊猴
365bet真人体育

日肖是哪几个生肖,兔龙蛇马羊猴

📅 08-17 👁️ 3389