解释为什么显示警告未经检查铸造source.readArrayList(data !!。javaClass.classLoader)为ArrayList <Data>?

this.data = source.readArrayList(data!!.javaClass.classLoader) as ArrayList<Data>? 

警告未选中cast:ArrayList <(raw)Any!>! 到ArrayList? coustom数据类的数据

通常,当您投射时,编译器会插入一个运行时检查来查看该投射是否有效。 例如:

 val s: String = f() as String 

在结果字节码checkcast有一个checkcast指令:

 checkcast java/lang/String 

这是一个运行时检查,看是否f()的结果实际上是一个String

但是由于泛型被擦除,一个ArrayList<Data>? 将只是一个ArrayList? 在运行时。

所以最好的虚拟机可以做的是检查你正在铸造的值是一个ArrayList? ,但它不能检查它是否实际上是一个ArrrayList<Data>? ,这就是为什么演员被称为“unchecked”。

因此对于:

 val a: List<String> = f() as List<String> 

你会得到:

 checkcast java/util/List 

注意这里String是如何丢失的。

但是,这并不意味着虚拟机会将您从列表中取出的任何值作为一个String盲目处理,这通常意味着将String其他String 。 例如,当你从列表中拿出一些东西时:

 val s: String = a[0] 

这变成:

 iconst_0 invokeinterface java/util/List.get:(I)Ljava/lang/Object; checkcast java/lang/String 

注意如何有一个checkcast String 。 编译器隐含地插入了这个转换,就好像代码实际上一样:

 val s: String = a[0] as String