简体   繁体   English

实现 Java 方法,该方法返回 Kotlin 中的集合

[英]Implement Java method that returns Collection in Kotlin

I'm using Kotlin with Spring Security.我正在使用 Kotlin 和 Spring 安全性。 When implementing this method:实现此方法时:

public interface UserDetails extends Serializable {
  Collection<? extends GrantedAuthority> getAuthorities();
  ...
}

I noticed Intellij generates this Kotlin code:我注意到 Intellij 生成了这个 Kotlin 代码:

override fun getAuthorities(): MutableCollection<out GrantedAuthority> { ... }

... which makes sense since java.util.Collection is mutable. ...这是有道理的,因为java.util.Collection是可变的。

However, if I replaced the MutableCollection with Collection (which should be kotlin.collections.Collection IIRC), the code still compiles fine.但是,如果我将MutableCollection替换为Collection (应该是kotlin.collections.Collection IIRC),代码仍然可以正常编译。 This confuses me because kotlin.collections.Collection is a read-only interface that MutableCollection inherits from.这让我很困惑,因为kotlin.collections.CollectionMutableCollection继承自的只读接口。 It doesn't make sense that I can return an immutable collection for a method that's declared to return a mutable collection.我可以为声明返回可变集合的方法返回不可变集合是没有意义的。

So my questions are:所以我的问题是:

  1. Why does using kotlin.collections.Collection not cause an error here?为什么在这里使用kotlin.collections.Collection不会导致错误?
  2. What's the correct Kotlin return type that's equivalent to java.util.Collection ?什么是与 java.util.Collection 等效的正确java.util.Collection返回类型?

The reason that this works is that Collection and MutableCollection are both equivalent to java.util.Collection .这样做的原因是CollectionMutableCollection等同于java.util.Collection You can see the full list of Java types that are mapped for Java interop here .您可以在此处查看为 Java 互操作映射的 Java 类型的完整列表。

This works because the non-mutable collection interfaces aren't actually immutable (for that, you'd want the Immutable Collections Library ), but they simply provide a read-only interface (as you note).这是有效的,因为非可变集合接口实际上不是不可变的(为此,您需要Immutable Collections Library ),但它们只是提供只读接口(如您所述)。 Since Java doesn't make this distinction, both have to be mapped to the same Java platform type.由于 Java 没有进行这种区分,因此两者都必须映射到相同的 Java 平台类型。

What's the correct Kotlin return type that's equivalent to java.util.Collection ?什么是与 java.util.Collection 等效的正确java.util.Collection返回类型?

The correct return type depends on the interface you want to expose to your Kotlin clients.正确的返回类型取决于您要向 Kotlin 客户端公开的接口。 If they shouldn't be mutating the returned collection, use Collection .如果他们不应该改变返回的集合,请使用Collection If you expect them to want to mutate it, use MutableCollection .如果您希望他们想要改变它,请使用MutableCollection For your Java clients, it doesn't matter: they're equivalent.对于您的 Java 客户端,这并不重要:它们是等效的。

  1. Why does using kotlin.collections.Collection not cause an error here?为什么在这里使用kotlin.collections.Collection不会导致错误?

If you're not aware, the mutable and non-mutable collection interfaces in Kotlin both resolve to one interface in Java.如果您不知道,Kotlin 中的可变和非可变集合接口都解析为 Java 中的一个接口。 So Kotlin's Collection and MutableCollection are both java.util.Collection in Java, Kotlin's List and MutableList are both java.util.List in Java, and so on. So Kotlin's Collection and MutableCollection are both java.util.Collection in Java, Kotlin's List and MutableList are both java.util.List in Java, and so on.

Also, Kotlin has what it terms declaration-site variance .此外, Kotlin 有它所说的声明站点差异 The Kotlin Collection interface is defined as Collection<out E> which means the interface is a producer of type E . Kotlin Collection接口定义为Collection<out E> ,这意味着该接口是类型E的生产者。 As a consequence, having:因此,具有:

val col: Collection<GrantedAuthority> = ...

Is nearly the same as:几乎与以下内容相同:

val col: MutableCollection<out GrantedAuthority> = ...

I say nearly because, while MutableCollection<out...> prevents anyone from adding any elements, it does not prevent one from mutating the collection entirely.我说几乎是因为,虽然MutableCollection<out...>阻止任何人添加任何元素,但它并不能阻止人们完全改变集合。 For example, you could still call clear() on the collection.例如,您仍然可以在集合上调用clear()


  1. What's the correct Kotlin return type that's equivalent to java.util.Collection ?什么是与 java.util.Collection 等效的正确java.util.Collection返回类型?

Java does not have declaration-site variance. Java 没有声明站点差异。 It also doesn't distinguish between mutable and non-mutable collections (at least not at the interface level).它也不区分可变和非可变 collections(至少在接口级别不区分)。

This means that, technically, the best match of the following Java type:这意味着,从技术上讲,以下 Java 类型的最佳匹配:

Collection<? extends GrantedAuthority>

Is the following Kotlin type:是以下 Kotlin 类型:

MutableCollection<out GrantedAuthority>

Both types are mutable collection types and are defined to be producers of type GrantedAuthority (via ? extends in Java and out in Kotlin).这两种类型都是可变集合类型,并被定义为GrantedAuthority类型的生产者(通过? extends out Neither type let's you add anything to the collection.这两种类型都不允许您向集合中添加任何内容。

However, if your getAuthorities() method is supposed to return an unmodifiable collection (eg Collections.unmodifiableCollection(collection) in Java) then the more appropriate conversion from Java to Kotlin would be to use:但是,如果您的getAuthorities()方法应该返回一个不可修改的集合(例如,Java 中的Collections.unmodifiableCollection(collection) ),那么从 Java 到 Z539A3A5859D24FFB7B11 的更合适的转换将是 use:74DA61

kotlin.collections.Collection<GrantedAuthority>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM