变量使用null初始化与空值初始化有什么区别?含多编程语言场景
两段代码的核心差异
这两段代码的语义有本质区别,在所有支持空引用/空指针的编程语言中都适用:
- 代码1是将变量赋值为空引用/空指针,代表该变量没有指向任何实际存在的对象实例,对其直接调用成员方法/访问属性一定会触发空错误。
- 代码2是将变量赋值为实际存在的空内容对象,是合法的实例,只是存储的内容为空,完全支持正常的方法调用和属性访问。
Dart/Flutter 场景
Dart 2.12及以上版本默认开启空安全,普通类型默认不允许赋值为null,你示例中代码1的null as String写法在非空类型下会直接抛出类型转换异常,只有声明为可空类型时才合法:String? a = null、List<T>? list = null。
- 可空的
String? a = null调用a.length会直接触发编译报错,强制运行时调用会抛出空指针异常;而String a = ''调用a.length会正常返回0,无任何错误。 - 列表同理,
List<T>? list = null调用list.add(xxx)会直接崩溃;List<T> list = []是有效的空列表实例,可以正常调用增删改查方法,只是初始没有存储元素。
其他主流编程语言的表现
C/C++
- 代码1对应写法:
char* a = NULL;/std::string* a = nullptr;、std::vector<T>* vec = nullptr;,本质是指针未指向任何有效内存地址,对其解引用会触发未定义行为,绝大多数情况会直接导致程序崩溃。 - 代码2对应写法:
char a[] = "";/std::string a = "";、std::vector<T> vec = {};,都是已经分配了内存的有效对象,strlen(a)/a.size()、vec.size()都会正常返回0,不会触发运行时错误。
Java
- 代码1对应写法:
String a = null;、List<T> list = null;,Java默认所有引用类型都支持赋值为null,对空引用调用任何成员方法都会抛出NullPointerException。 - 代码2对应写法:
String a = "";、List<T> list = new ArrayList<>();,是已实例化的有效对象,调用a.length()、list.size()都会返回0,支持正常操作。
JavaScript
- 代码1对应写法:
let a = null;、let list = null;,访问空值的属性如a.length会直接抛出类型错误。 - 代码2对应写法:
let a = '';、let list = [];,是合法的字符串、数组实例,a.length、list.length都会返回0,支持正常调用各类内置方法。
Python
- 代码1对应写法:
a = None、list = None,调用len(a)等内置方法或者访问属性会抛出类型错误。 - 代码2对应写法:
a = ''、list = [],是合法的字符串、列表实例,len(a)、len(list)都会返回0,支持正常操作。
内容的提问来源于stack exchange,提问作者user11874694
相关产品推荐
相关产品推荐

