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

调用onCreateViewHolder触发NoSuchMethodException的问题求助

解决反射调用onCreateViewHolder时的NoSuchMethodException问题

你的问题核心出在两个地方:反射目标类不匹配和参数类型传递错误,下面一步步拆解解决:

1. 先理清Companion Object方法的反射规则

Kotlin的companion object中的方法,默认在Java字节码里属于CountryDataItem$Companion这个内部类的实例方法,而非CountryDataItem类的静态方法。如果直接用CountryDataItem::class.java去获取方法,肯定找不到——因为方法根本不在这个类里。

解决办法二选一:

  • 推荐方案:给方法加@JvmStatic注解
    加上这个注解后,Kotlin会自动生成CountryDataItem类的静态方法,反射时直接操作CountryDataItem类即可:
    companion object {
        @JvmStatic // 关键注解
        fun onCreateViewHolder(
            parent: ViewGroup,
            onRecyclerItemClickListener: OnRecyclerItemClickListener?
        ): RecyclerView.ViewHolder {
            val view = LayoutInflater.from(parent.context).inflate(R.layout.country_item, parent, false)
            return CountryViewHolder(view) // 别忘了返回ViewHolder实例,你原代码漏写了
        }
    }
    
  • 备选方案:直接反射Companion类
    如果不想加注解,需要先获取CountryDataItem$Companion类的Class对象,再获取方法:
    val companionClass = Class.forName("your.package.name.CountryDataItem\$Companion")
    

2. 参数类型必须严格匹配方法声明

你之前传递的是AllScoresFragment的Class,但方法定义的第二个参数是OnRecyclerItemClickListener?,反射时必须传入方法声明的参数类型的Class,而非对象的实际运行时类型。

哪怕你把对象强转成OnRecyclerItemClickListener,castedVariable.javaClass返回的还是AllScoresFragment.class(因为javaClass获取的是对象的真实类型),这和方法声明的参数类型不匹配,所以反射找不到方法。

正确的参数类型传递:

直接传入接口的Class对象OnRecyclerItemClickListener::class.java即可,不管实际实现类是什么:

// 如果加了@JvmStatic
val method = CountryDataItem::class.java.getMethod(
    "onCreateViewHolder",
    ViewGroup::class.java,
    OnRecyclerItemClickListener::class.java
)

// 调用方法(静态方法invoke第一个参数传null)
val viewHolder = method.invoke(
    null,
    parent,
    onRecyclerItemClickListenerRef.get()
) as RecyclerView.ViewHolder

如果是用Companion类反射:

val method = companionClass.getMethod(
    "onCreateViewHolder",
    ViewGroup::class.java,
    OnRecyclerItemClickListener::class.java
)
// 调用时需要传入Companion实例
val viewHolder = method.invoke(
    CountryDataItem.Companion,
    parent,
    onRecyclerItemClickListenerRef.get()
) as RecyclerView.ViewHolder

额外提醒

你原代码中的onCreateViewHolder方法没有返回ViewHolder实例,这会导致编译错误,记得补充返回逻辑哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:25:48