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

Koin升级至2.2.2后编译报错:Cannot use 'VM' as reified type parameter. Use a class instead

Fix Koin 2.2.2 Compilation Error: "Cannot use 'VM' as reified type parameter"

Hey there, let's work through this Koin upgrade issue you're hitting. I ran into a nearly identical problem when jumping from Koin 2.0.x to 2.2+, so I know exactly what's going on here.

Why This Happens

In Koin 2.0.1, the viewModel() delegate had a handy overload that accepted a KClass<VM> parameter—perfect for your generic base class setup. But starting with Koin 2.2.x, the team shifted the core viewModel() implementation to rely on reified type parameters. The catch? Your VM is a generic type parameter, and the compiler can't "reify" it (meaning it can't lock in the concrete type at compile time), which triggers that error message.

Solution 1: Use getViewModel() with lazy

The quickest fix is to swap out the by viewModel(clazz) delegate with a lazy block that uses Koin's getViewModel() function. This function still supports passing a KClass directly, so it plays nicely with your generic setup:

abstract class ActivityBaseViewModel<out VM : ViewModel>(clazz: KClass<VM>) : AppCompatActivity() {
    protected val viewModel: VM by lazy {
        getViewModel(clazz = clazz)
    }
}

This keeps the same lazy initialization behavior as your original code while aligning with Koin's updated API.

Solution 2: Keep the Delegate with a Factory Lambda

If you prefer sticking with the by viewModel() syntax, you can pass a factory lambda to the delegate that fetches the ViewModel using your provided KClass:

abstract class ActivityBaseViewModel<out VM : ViewModel>(clazz: KClass<VM>) : AppCompatActivity() {
    protected val viewModel: VM by viewModel {
        get(clazz)
    }
}

This works because the lambda gives you access to Koin's get() function, which still accepts a KClass parameter.

Bonus: Simplify Subclass Usage (Optional)

If you want to eliminate passing KClass to every subclass, you can refactor the base class to let subclasses provide the reified type directly. Here's how that looks:

abstract class ActivityBaseViewModel<VM : ViewModel> : AppCompatActivity() {
    protected abstract val viewModel: VM
}

// In your subclass:
class HomeActivity : ActivityBaseViewModel<HomeViewModel>() {
    override val viewModel: HomeViewModel by viewModel()
}

This removes the need for passing KClass entirely, though it does require each subclass to explicitly declare its ViewModel type and override the property.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 16:17:47