如何将一个集合的内容添加到新集合中

时间:2014-10-04 11:54:25

标签: generics collections kotlin

我试图覆盖调用超类的方法并将返回的值添加到新集合中(这是必需的,因为超类'返回值是不可变的)。

这个惯用的Java如下:

public class JaxrsApplication extends Application {

    @Override public Set<Class<?>> getClasses() {
        HashSet<Class<?>> classes = new HashSet<>(super.getClasses());
        classes.add(PlainTextWriter.class);
        classes.add(PageResource.class);
        return classes;
    }
}

我试图在Kotlin中实现一个等价物而没有成功:

public class JaxrsApplication() : Application() {

    override fun getClasses(): MutableSet<Class<out Any?>>? {
        val classes = hashSetOf<Class<out Any?>>() 
        classes.addAll(super.getClasses())          // <= compiler error!
        classes.add(javaClass<PlainTextWriter>())
        classes.add(javaClass<PageResource>())
        return classes
    }

}

这似乎是addAll函数的类型推断问题,但我不确定如何解决它。帮助赞赏: - )


对于未来的读者,我在这里感到困惑的原因是由于错误弹出窗口中的类型不匹配:

error pop-up

MutableSet实施Iterable,此处的关键是最终的&#39;?&#39;发现&#39;上的角色表示返回值的行可以为空。

2 个答案:

答案 0 :(得分:2)

您收到编译器错误,因为super.getClasses返回nullable类型,但addAll仅接受not-null参数。

可以使用if-statement!!运营商解决此问题:

1

val superClasses = super.getClasses()
if (superClasses != null) {
    classes.addAll(superClasses)
}

2

classes.addAll(super.getClasses()!!)

答案 1 :(得分:0)

在Kotlin M9中你不应该再遇到这个问题了。它具有不同类型系统的概念,或“平台类型”,Java和JavaScript平台类型与Kotlin类型不同且更宽松。因此,您可以在不允许使用更具体的Kotlin类型的地方使用可能为空的Java平台类型。例如,Java方法返回一个可能为null的值,然后推断的类型将是Java平台类型,并且您可以将其传递给禁用空检查的其他事项,因为Java是未知的。如果你专门给它一个Kotlin类型而不使用类型推断,那么你将它强制转换为更严格的空值检查,并且在那行代码中,Kotlin会声明该值对于你来说不是空的(与之前使用!!相同) 。

所以在M9中,你有两个选择。让Java类型丢失并导致可能的问题。或者告诉Kotlin你想把它专门视为可空或非空,或者使用旧的!断言。