我有一个不变的对象:
class Foo(
val name: String,
val things: List<Thing>
)
第三方库使用一些“空” Thing对象创建Foo对象。
我正在创建一个新对象:
val foo = thirdPartyGetFoo()
val filteredFoo = Foo(foo.name, foo.things.filterNotNull())
可以,但是AndroidStudio使filterNotNull函数调用变灰并发出警告:
无用的回收类型:检查报告类似过滤器 调用已过滤的集合。
这是过滤列表的正确方法吗?我应该忽略警告还是有更好的方法?
答案 0 :(得分:0)
您没有指定哪个库创建带有空值的对象。某些反序列化库可以使用可以配置的静态工厂方法,然后让工厂方法去除null。例如,如果这是杰克逊,则只需:
class Foo(val name: String, val things: List<Thing>) {
companion object {
@JsonCreator
@JvmName("createFromNullable")
fun create(name: String, things: List<Thing?>) = Foo(name, things.filterNotNull())
fun create(name: String, things: List<Thing>) = Foo(name, things)
}
}
然后...
val goodFoo = jacksonObjectMapper().readValue<Foo>(someJsonWithNulls)
也许您的图书馆有类似的选择?
如果没有,并且您没有100个此类问题,我可能会创建一个临时类来保存结果并将其转换为最终类:
open class FooNullable(val name: String, open val things: List<Thing?>) {
open fun withoutNulls(): Foo = Foo(name, things.filterNotNull())
}
class Foo(name: String, override val things: List<Thing>) : FooNullable(name, things) {
override fun withoutNulls(): Foo = this
}
然后,您可以反序列化为FooNullable
,只需调用withoutNulls()
即可获得另一种干净的味道。而且,如果您不小心调用了一个没有空值的函数,它什么也没做。
val goodFoo = Foo("", emptyList<Thing>())
val alsoGoodFoo = goodFoo.withoutNulls() // NOOP does nothing
val badFoo = thirdPartyGetFoo()
val betterFoo = badFoo.withoutNulls() // clean up the instance
val safeFoo = thirdPartyGetFoo().withoutNulls() // all at once!
不是最干净的,但是可以工作。缺点是第二步,尽管您似乎已经计划这样做。但是,此模型比您所建议的模型更安全,因为您知道拥有哪种类型的对象,因此仍然可以保持类型安全,并需要编译器来帮助您避免错误。
您不必在上面的示例中使用继承,我只是在试图统一API的情况下,以防万一有一个版本可以掌握哪个版本,并且知道哪个版本,并在一个版本中对其进行操作。类似的方式。