Flutter疑问:SharedPreferences为空时未触发未处理异常的原因
问题分析与解决
嘿,这个问题的核心在于你对SharedPreferences.getString()的返回值和Dart中null比较的行为理解有点偏差,我来一步步拆解:
1. 为什么运行时没崩溃也没抛出异常?
首先,SharedPreferences.getString()当指定的键不存在时,返回的是**null**,而不是空字符串''。你的代码里写的是:
if (preferences.getString(USER_TOKEN_PREFERENCE) != '') { yield AuthentificationStatus.passed; }
在Dart中,null != ''是一个合法的布尔表达式,结果为true——因为null和空字符串是完全不同的类型/值,所以这个条件会成立,代码会直接进入if块执行,整个过程没有任何非法操作,自然不会抛出异常或导致崩溃。
2. 为什么调试控制台求值时会触发异常?
你提到调试时求值会触发未处理异常,大概率是因为你在调试时直接对preferences.getString(USER_TOKEN_PREFERENCE)的返回值(也就是null)执行了字符串专属的操作——比如查看它的length属性、调用trim()方法,或者在调试表达式里做了强制类型转换。这些操作会因为null不是字符串实例而抛出异常,但你的运行时代码里只是做了简单的!=比较,并没有这些操作,所以运行时不会暴露这个问题。
3. 正确的写法应该是怎样的?
要正确判断token存在且非空,你需要同时检查null和空字符串两种情况,推荐用空安全的写法:
final SharedPreferences preferences = await _preferences; final token = preferences.getString(USER_TOKEN_PREFERENCE); // 先判断token不为null,再判断不是空字符串 if (token != null && token.isNotEmpty) { yield AuthentificationStatus.passed; } // 或者更简洁的空安全语法 if (token?.isNotEmpty ?? false) { yield AuthentificationStatus.passed; }
这样就能确保只有当token确实存在且不是空字符串时,才会进入认证通过的逻辑。
内容的提问来源于stack exchange,提问作者Jérôme
相关产品推荐
相关产品推荐

