解释为什么显示警告未经检查铸造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