Kotlin密封类中Data Object为null导致底部Tab元素缺失问题排查
Kotlin密封类中Sinif对象未出现在遍历结果中的原因分析
问题描述
我用Kotlin密封类TabanSevkHedefiMuta定义了Sinif、Talebe、Vazife、Tavir四个data object,用于填充底部Tab栏。但通过伴生对象里listOfNotNull创建的hedefler列表遍历时,日志只输出Talebe、Vazife、Tavır三个元素,Sinif疑似变为null被过滤了,请问这是怎么回事?
相关代码
密封类定义
sealed class TabanSevkHedefiMuta( val ibre: Int, val hedef: String, val nisaneSerbest: ImageVector, val yafta: String ) { data object Sinif : TabanSevkHedefiMuta( ibre = 1, hedef = "sinif", nisaneSerbest = Icons.Filled.School, yafta = "Sınıf" ) data object Talebe : TabanSevkHedefiMuta( ibre = 2, hedef = "talebe", nisaneSerbest = Icons.Filled.Person, yafta = "Talebe" ) data object Vazife : TabanSevkHedefiMuta( ibre = 3, hedef = "vazife", nisaneSerbest = Icons.Filled.Book, yafta = "Vazife" ) data object Tavir : TabanSevkHedefiMuta( ibre = 4, hedef = "tavir", nisaneSerbest = Icons.Filled.Handshake, yafta = "Tavır" ) companion object { val hedefler = listOfNotNull(Sinif, Talebe, Vazife, Tavir) } }
遍历代码
TabanSevkHedefiMuta.hedefler.forEach { tabanSevkHedefiMuta -> Ikazci.izahEt(izahat = "tabanSevkHedefiMuta: ${tabanSevkHedefiMuta.yafta}") }
日志输出
tabanSevkHedefiMuta: Talebe tabanSevkHedefiMuta: Vazife tabanSevkHedefiMuta: Tavır
核心原因
listOfNotNull的作用是自动过滤所有null元素,而Sinif被过滤的本质是该data object在初始化过程中抛出了未捕获的异常,导致实例变为null。
具体来看,Sinif的构造参数nisaneSerbest = Icons.Filled.School是关键:密封类(及伴生对象)通常在App启动阶段就会被加载,此时Icons.Filled.School对应的图标资源可能还未完成初始化,创建图标对象时抛出异常,直接导致Sinif实例化失败,最终在listOfNotNull中被判定为null并过滤。
验证方式
可以在伴生对象中直接打印Sinif的状态来确认:
companion object { val hedefler = run { println("Sinif是否为null:${Sinif == null}") listOfNotNull(Sinif, Talebe, Vazife, Tavir) } }
如果打印结果为Sinif是否为null:true,就印证了初始化异常导致实例为null的猜想。
解决方案
- 延迟初始化列表:用
lazy延迟加载hedefler,确保在图标资源可用后再初始化,同时改用listOf(正常情况下data object不会为null):
companion object { val hedefler by lazy { listOf(Sinif, Talebe, Vazife, Tavir) } }
- 容错处理图标初始化:用
runCatching包裹图标初始化逻辑,即使加载失败也返回默认图标,保证Sinif实例正常创建:
data object Sinif : TabanSevkHedefiMuta( ibre = 1, hedef = "sinif", nisaneSerbest = runCatching { Icons.Filled.School }.getOrElse { Icons.Filled.Error }, yafta = "Sınıf" )
内容的提问来源于stack exchange,提问作者vareste
相关产品推荐
相关产品推荐

