[英]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.Collection
是MutableCollection
继承自的只读接口。 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:所以我的问题是:
kotlin.collections.Collection
not cause an error here?kotlin.collections.Collection
不会导致错误?java.util.Collection
?java.util.Collection
返回类型?The reason that this works is that Collection
and MutableCollection
are both equivalent to java.util.Collection
.这样做的原因是
Collection
和MutableCollection
都等同于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 客户端,这并不重要:它们是等效的。
- 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()
。
- 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.