我在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.CollectionMutableCollection继承的只读接口(interface)。我可以为声明为返回可变集合的方法返回不可变集合是没有意义的。
所以我的问题是:
  • 为什么在这里使用kotlin.collections.Collection不会导致错误?
  • 什么是等效于java.util.Collection的正确Kotlin返回类型?
  • 最佳答案


    如果您不知道,那么Kotlin中的可变和非可变collection接口(interface)都会解析为Java中的一个接口(interface)。因此Kotlin的CollectionMutableCollection在Java中都是java.util.Collection,Kotlin的ListMutableList在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/

    10-16 23:46