我在Spring Security中使用Kotlin。实现此方法时:
public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
...
}
我注意到Intellij生成此Kotlin代码:override fun getAuthorities(): MutableCollection<out GrantedAuthority> { ... }
...这是有意义的,因为java.util.Collection
是可变的。但是,如果我将
MutableCollection
替换为Collection
(应为kotlin.collections.Collection
IIRC),则代码仍然可以正常编译。这使我感到困惑,因为kotlin.collections.Collection
是MutableCollection
继承的只读接口(interface)。我可以为声明为返回可变集合的方法返回不可变集合是没有意义的。所以我的问题是:
kotlin.collections.Collection
不会导致错误? java.util.Collection
的正确Kotlin返回类型? 最佳答案
如果您不知道,那么Kotlin中的可变和非可变collection接口(interface)都会解析为Java中的一个接口(interface)。因此Kotlin的Collection
和MutableCollection
在Java中都是java.util.Collection
,Kotlin的List
和MutableList
在Java中都是java.util.List
,依此类推。
同样,Kotlin的术语是declaration-site variance。 Kotlin Collection
接口(interface)定义为Collection<out E>
,这意味着该接口(interface)是E
类型的生产者。结果,具有:
val col: Collection<GrantedAuthority> = ...
与以下内容几乎相同:val col: MutableCollection<out GrantedAuthority> = ...
我说这几乎是因为MutableCollection<out ...>
可以阻止任何人添加任何元素,但不能阻止一个人完全改变集合。例如,您仍然可以在集合上调用clear()
。Java没有声明站点差异。它也没有区分可变集合和非可变集合(至少在接口(interface)级别上没有)。
从技术上讲,这意味着以下Java类型的最佳匹配:
Collection<? extends GrantedAuthority>
是以下Kotlin类型:MutableCollection<out GrantedAuthority>
这两种类型都是可变的集合类型,并被定义为GrantedAuthority
类型的生产者(通过Java中的? extends
和Kotlin中的out
)。两种类型都不能让您向集合中添加任何内容。但是,如果您的
getAuthorities()
方法应该返回不可修改的集合(例如Java中的Collections.unmodifiableCollection(collection)
),则从Java到Kotlin的更合适的转换将是使用:kotlin.collections.Collection<GrantedAuthority>
关于java - 在Kotlin中实现返回Collection的Java方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63128815/