Dart泛型类SharedPreferencesObserver解析JSON遇类型转换错误,如何调用fromJson?
解决Dart泛型类中调用fromJson解析JSON的问题
问题原因
直接执行json.decode(jsonString) as T会抛出类型转换异常,因为json.decode返回的是Map<String, dynamic>类型,而非AuthResponse实例。Dart泛型无法直接调用T.fromJson静态方法,因为泛型在运行时会擦除类型信息,静态方法属于类本身而非实例,无法通过泛型参数直接访问。
解决方案1:传递解析函数到泛型类构造函数
这是最直接灵活的方案,无需修改现有实体类结构,只需在创建泛型实例时传入对应的fromJson工厂方法。
修改后的SharedPreferencesObserver类
import 'dart:convert'; import 'package:flutter/foundation.dart'; // 假设你已定义SharedPreferencesManager class SharedPreferencesObserver<T> extends ChangeNotifier { late String _keyParam; T? _value; SharedPreferencesObserver( String key, T Function(Map<String, dynamic>) fromJson, // 新增解析函数参数 ) { _keyParam = key; final jsonString = SharedPreferencesManager.instance.getString(key); try { if (jsonString != null) { final jsonMap = json.decode(jsonString) as Map<String, dynamic>; _value = fromJson(jsonMap); // 使用传入的解析函数创建实例 } else { _value = null; } } catch (e) { _value = null; } } // 获取当前值 T? get value => _value; }
使用示例
创建AuthResponse对应的观察者实例时,直接传入AuthResponse.fromJson:
final authObserver = SharedPreferencesObserver<AuthResponse>( 'auth_token_key', AuthResponse.fromJson, );
解决方案2:通过抽象类约束+解析函数
如果希望通过抽象类统一约束所有可序列化的实体类,可以定义一个抽象类,让实体类实现它,再结合解析函数使用。
定义抽象类
abstract class JsonSerializable<T> { factory JsonSerializable.fromJson(Map<String, dynamic> json) = T; }
修改AuthResponse实现抽象类
class AuthResponse extends JsonSerializable<AuthResponse> { final String token; AuthResponse({required this.token}); Map<String, dynamic> toJson() { return { 'token': token, }; } @override factory AuthResponse.fromJson(Map<String, dynamic> json) { return AuthResponse( token: json['token'], ); } }
泛型类添加约束
修改泛型类,限定T必须实现JsonSerializable<T>,同时仍需传入解析函数(因为静态方法无法通过泛型参数直接调用):
class SharedPreferencesObserver<T extends JsonSerializable<T>> extends ChangeNotifier { late String _keyParam; T? _value; SharedPreferencesObserver( String key, T Function(Map<String, dynamic>) fromJson, ) { _keyParam = key; final jsonString = SharedPreferencesManager.instance.getString(key); try { if (jsonString != null) { final jsonMap = json.decode(jsonString) as Map<String, dynamic>; _value = fromJson(jsonMap); } else { _value = null; } } catch (e) { _value = null; } } T? get value => _value; }
使用示例
和方案1一致,传入AuthResponse.fromJson即可:
final authObserver = SharedPreferencesObserver<AuthResponse>( 'auth_token_key', AuthResponse.fromJson, );
总结
方案1无需修改实体类,灵活性更高,是更推荐的实现方式;方案2通过抽象类统一约束实体类,适合需要统一管理序列化逻辑的场景。两种方案核心都是通过传递解析函数,绕过泛型无法直接调用静态方法的限制,将JSON Map转换为目标实体类实例。
内容的提问来源于stack exchange,提问作者Karatekid430
相关产品推荐
相关产品推荐

