BRVAH_kotlin
BRVAH_kotlin copied to clipboard
Adapter泛型问题
当我在OnItemClickListener中通过adapter.data获取数据的时候,我已经指定了数据类型,但是它还是要我强转成已经指定的数据类型:
mAdapter?.setOnItemClickListener { adapter, view, position ->
val adapterData: MutableList<MessageData> = adapter.data as MutableList<MessageData>
}
``
方式一 写法 不需要
adapter.onItemClickListener = BaseQuickAdapter.OnItemClickListener { _, _, position ->
Log.d(TAG, "onItemClick: ")
toast("onItemClick" + position)
val adapterData: MutableList<ClickEntity> = adapter.data
toast(adapterData.size)
}
方式二写法需要
adapter.setOnItemLongClickListener{ adapter, view, position ->
Log.d(TAG, "onItemClick: ")
toast("onItemClick" + position)
val adapterData: MutableList<ClickEntity> = adapter.data as MutableList<ClickEntity>
toast(adapterData.size)
true
}
原因 在于:

第一种 情况下 是全局 adapter ,IDE 根据 当前加载类推断出 data数据的类型 为 第二种情况下,adapter是通过接口传入的参数,ide通过静态类型分析只能推断出 原始数据类型为
/**
* Get the data of list
*
* @return 列表数据
*/
@NonNull
public List<T> getData() {
return mData;
}
无法向下推断具体的子类型 ,所以提示需要强转 。
val adapterData: MutableList<MessageData> = adapter.data as MutableList<MessageData>
解释一下,不论kotlin,还是java,这都需要 显式转换 类型。编译器无法安全的 隐式转换。这是语法基础。
val adapterData: MutableList<MessageData>
这里,你定义了一个变量 adapterData ,由于你已经强制指定类型 MutableList<MessageData> ,所以,编译器不再自动进行类型推断。
类似于 java 中的这个:MutableList<MessageData> adapterData = ……
由于adapterData已经确定了类型为MutableList<MessageData>,所以它只能接收该种类型的数据。
然后解释下等号后面的:
首先这里返回的adapter是父类BaseQuickAdapter<T>,而不是你自定义的子类adapter。
如果这里返回的是 你自己写的adapter,那么就可以直接得到具体的T参数类型。
而对于父类BaseQuickAdapter<T>,所得到的data是一个任意类型Any,而不是具体的类型。
所以adapter.data所得到的Any怎么能直接赋值给adapterData呢?adapterData是明确指定了是MutableList<MessageData>类型。
我再给你举一个例子:
val a :Any = ""
val b: String = a //错误,Any类型无法赋值给String类型
val b: String = a as String //正确,显式转换为String
val b = a // 正确,此处的b,编译器自动类型推断为Any类型,b与a同为Any
希望你能理解