如何序列化/反序列化Kotlin中的自定义对象数组?

在我的Kotlin Android项目中,我做了一个扩展Serializable的FileItem类

class FileItem(<parameters>) : Serializable, Comparable<FileItem> { 

所以我需要将这个类的实例序列化成一个Bundle

 val arguments:Bundle = Bundle() arguments.putSerializable("folders", folders as Serializable) 

文件夹已被声明为:

 folders:Array<FileItem> (method parameter) 

上面的序列化代码编译没有任何警告。 同时,当我需要反序列化文件夹项目时出现问题:

 val arguments: Bundle? = getArguments() if (arguments != null){ foldersItems = arguments.getSerializable("folders") as Array<FileItem> 

其中foldersItems被声明为

 var foldersItems: Array<FileItem>? 

我得到以下警告,我不能设法解决没有suppress_warning注释

 w: <Path to my class>: (78, 28): Unchecked cast: java.io.Serializable! to kotlin.Array<com.loloof64.android.chess_positions_archiver.main_file_explorer.FileItem> 

这种代码在Java / Groovy中编译没有任何警告(folderItems然后是FileItem []),那么如何修改编译器的kotlin代码以“满意”?

我在官方的Kotlin文档中注意到,Kotlin数组不能扩展Serializable,也不能继承。 是否有可能通过一种扩展方法来“添加”它?

实际上,演员阵容不是不受控制的,编译器的警告是误导性的。

发生这种情况是因为在Kotlin中,数组由泛型类Array<T> ,编译器将其视为通常的泛型类,并在运行时删除类型参数。

但是在JVM 数组上有具体化的类型 ,并且当你将something as Array<SomeType> ,生成的字节码确实将类型参数检查为SomeType以及某个Array<*> ,这只会发生在其他任何泛型类。

此示例显示数组转换已检查:

 val a: Any = Array<Int>(1) { 0 } val i = a as Array<Int> val d = a as Array<Double> // gets checked and throws ClassCastException 

最简单的解决方案实际上是@Suppress("UNCHECKED_CAST") ,因为实际上不应该有任何警告。

我在Kotlin问题跟踪器中提出描述问题的问题。

这里的转换没有被选中,因为这里的编译器不能确保数组泛型类型参数的可空性

考虑下面的例子:

 fun castAsArrayOfString(param: Any) = param as Array<String> castAsArrayOfString(arrayOf("a")) // is Array<String>, all ok castAsArrayOfString(arrayOf("a", null)) // is Array<String>, but contains null 

所以编译器会警告你这个类型可能引入的潜在类型安全问题。