BRVAH_kotlin icon indicating copy to clipboard operation
BRVAH_kotlin copied to clipboard

Adapter泛型问题

Open Dod023 opened this issue 6 years ago • 3 comments

当我在OnItemClickListener中通过adapter.data获取数据的时候,我已经指定了数据类型,但是它还是要我强转成已经指定的数据类型:

Dod023 avatar Jul 20 '19 06:07 Dod023

 mAdapter?.setOnItemClickListener { adapter, view, position ->
            val adapterData: MutableList<MessageData> = adapter.data as MutableList<MessageData>
        }
``

Dod023 avatar Jul 20 '19 07:07 Dod023

方式一 写法 不需要

       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
        }

原因 在于: image

第一种 情况下 是全局 adapter ,IDE 根据 当前加载类推断出 data数据的类型 为 第二种情况下,adapter是通过接口传入的参数,ide通过静态类型分析只能推断出 原始数据类型为


    /**
     * Get the data of list
     *
     * @return 列表数据
     */
    @NonNull
    public List<T> getData() {
        return mData;
    }

无法向下推断具体的子类型 ,所以提示需要强转 。

AllenCoder avatar Jul 24 '19 15:07 AllenCoder

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

希望你能理解

limuyang2 avatar Jul 24 '19 15:07 limuyang2