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

如何为Any类型的ArrayList指定类类型,适配多来源不同类型列表

解决方案

Kotlin 泛型为编译期检查,运行时会发生类型擦除,因此无法在运行时动态修改 ArrayList 的已声明泛型类型,可通过以下两种方案实现动态适配不同数据类型的需求:

方案1:密封类封装(推荐,类型安全)

通过密封类统一封装三种列表类型,借助 Kotlin 智能转换实现编译期类型安全:

  1. 定义密封类包裹所有支持的列表类型
// 先定义你业务中的三种数据类,示例如下
data class User(val id: Int, val name: String)
data class Order(val orderId: String, val amount: Long)
data class Goods(val goodsId: String, val price: Long)

// 定义列表类型密封类
sealed class BusinessList {
    data class UserList(val list: ArrayList<User>) : BusinessList()
    data class OrderList(val list: ArrayList<Order>) : BusinessList()
    data class GoodsList(val list: ArrayList<Goods>) : BusinessList()
}
  1. Service 中修改变量定义
// 替换原有的lateinit var list: ArrayList<Any>
private lateinit var businessList: BusinessList
  1. 接收 Intent 时按类型赋值
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    intent ?: return super.onStartCommand(intent, flags, startId)
    // 从Intent中取提前约定的类型标记
    when(intent.getIntExtra("LIST_TYPE", -1)) {
        0 -> {
            val list = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                intent.getSerializableExtra("DATA", ArrayList::class.java) as ArrayList<User>
            } else {
                @Suppress("UNCHECKED_CAST")
                intent.getSerializableExtra("DATA") as ArrayList<User>
            }
            businessList = BusinessList.UserList(list)
        }
        1 -> {
            val list = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                intent.getSerializableExtra("DATA", ArrayList::class.java) as ArrayList<Order>
            } else {
                @Suppress("UNCHECKED_CAST")
                intent.getSerializableExtra("DATA") as ArrayList<Order>
            }
            businessList = BusinessList.OrderList(list)
        }
        2 -> {
            val list = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                intent.getSerializableExtra("DATA", ArrayList::class.java) as ArrayList<Goods>
            } else {
                @Suppress("UNCHECKED_CAST")
                intent.getSerializableExtra("DATA") as ArrayList<Goods>
            }
            businessList = BusinessList.GoodsList(list)
        }
    }
    return super.onStartCommand(intent, flags, startId)
}
  1. 处理数据时自动匹配类型,无需手动强转
fun handleBusinessData() {
    when(businessList) {
        is BusinessList.UserList -> {
            val userList = businessList.list // 智能推导为 ArrayList<User>
            // 处理用户列表逻辑
        }
        is BusinessList.OrderList -> {
            val orderList = businessList.list // 智能推导为 ArrayList<Order>
            // 处理订单列表逻辑
        }
        is BusinessList.GoodsList -> {
            val goodsList = businessList.list // 智能推导为 ArrayList<Goods>
            // 处理商品列表逻辑
        }
    }
}

方案2:保留 ArrayList 定义,运行时校验类型

如果无需严格编译期类型校验,可直接使用原有定义,使用前做类型检查:

  • 赋值逻辑:
private lateinit var targetList: ArrayList<Any>

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    intent ?: return super.onStartCommand(intent, flags, startId)
    targetList = when(intent.getIntExtra("LIST_TYPE", -1)) {
        0 -> {
            @Suppress("UNCHECKED_CAST")
            intent.getSerializableExtra("DATA") as ArrayList<User>
        }
        1 -> {
            @Suppress("UNCHECKED_CAST")
            intent.getSerializableExtra("DATA") as ArrayList<Order>
        }
        2 -> {
            @Suppress("UNCHECKED_CAST")
            intent.getSerializableExtra("DATA") as ArrayList<Goods>
        }
        else -> arrayListOf()
    } as ArrayList<Any>
    return super.onStartCommand(intent, flags, startId)
}
  • 使用逻辑:
fun handleData() {
    when {
        targetList.all { it is User } -> {
            val userList = targetList.filterIsInstance<User>()
            // 处理用户列表
        }
        targetList.all { it is Order } -> {
            val orderList = targetList.filterIsInstance<Order>()
            // 处理订单列表
        }
        targetList.all { it is Goods } -> {
            val goodsList = targetList.filterIsInstance<Goods>()
            // 处理商品列表
        }
    }
}

注意点

  • Fragment 传值给 Service 时,需要提前在 Intent 中放入约定好的 LIST_TYPE 标记,和对应的列表数据
  • Android 13 及以上版本建议使用带类型参数的 getSerializableExtra 接口,降低类型转换风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 15:48:02