You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin类内val字段调用Color.parseColor赋值后求值结果为0异常

问题原因分析

最高概率原因:类初始化顺序异常,属性未完成初始化就被访问

Kotlin 类的初始化顺序严格遵循如下逻辑:

  • 执行父类的主构造函数/init块/次级构造函数
  • 按声明顺序执行子类的成员属性初始化
  • 执行子类的构造函数体

如果父类的构造逻辑中调用了被子类重写的open方法,且该方法访问了子类的成员属性,此时子类的属性还未完成初始化,会直接返回对应类型的默认值,Int 类型的默认值就是0,完全匹配你遇到的现象。

复现代码示例

open class BaseView {
    constructor(context: Context) {
        // 父类构造中调用open方法
        initView()
    }
    open fun initView() {}
}

class CoffeeView(context: Context): BaseView(context) {
    // 子类属性初始化晚于父类构造执行
    private val COLOR_COFFEE = Color.parseColor("#6F4E37")
    
    override fun initView() {
        // 此时访问COLOR_COFFEE会得到默认值0
        Log.d("init", COLOR_COFFEE.toString())
    }

    fun test(){
        // 类初始化完成后访问,属性已赋值,结果正常
        Log.d("test", "${COLOR_COFFEE} ${Color.parseColor("#6F4E37")}")
    }
}

其他可能原因

  • 你使用了反射直接访问该属性的幕后字段,此时如果属性还未完成赋值(比如使用by lazy初始化还未触发),会返回默认值0
  • 项目接入了存在bug的字节码修改插件、Kotlin编译器插件,篡改了属性的初始化逻辑
解决方案
  1. 优先排查父类构造逻辑中是否调用了子类重写的方法,禁止在父类构造函数中调用open方法
  2. 如果必须在初始化早期访问该属性,可以将属性改为by lazy初始化,访问时会主动触发赋值逻辑:
private val COLOR_COFFEE by lazy { Color.parseColor("#6F4E37") }
  1. 如果是自定义View相关场景,可以将颜色值放到res/values/colors.xml中,通过Context加载颜色,避免硬编码解析。

内容的提问来源于stack exchange,提问作者mickstar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 04:15:04