我在Kotlin中有一个方法,它返回一个通用列表的Rx Observable:
public fun getObservable(): Observable<List<FooBar>> {
return Observable.just(theList)
}
由于Kotlin列表特征定义为List<out T>
,因此Java会将返回类型视为Observable<List<? extends FooBar>>
。
有没有办法告诉Kotlin编译器Java应该将其视为Observable<List<FooBar>>
?
http://kotlinlang.org/docs/reference/generics.html
已更新以正确显示问题。
答案 0 :(得分:6)
您可以使用JvmWildcard
和JvmSuppressWildcards
注释来控制Java如何看待Kotlin泛型。它被添加到Kotlin 1.0 Beta 4中(参见announcement)。
此更改意味着您的代码已经更改为正常,并且不再生成通配符。因为新的默认设置是在许多情况下不使用它们,并且您可以使用注释将它们带回来或在不需要时禁止它们。
此变更的公告声明:
Java通配符
Kotlin如何翻译变体类型存在问题,例如: List是List应该是Java还是List。除了细微之处,我们做了以下几点:
- 默认情况下,我们不会在返回类型中生成通配符,也不会生成无意义的通配符
- 当需要通配符时,可以使用类型注释强制其存在:List&lt; @JvmWildcard String&gt;始终是Java中的List
- 当我们需要删除通配符时,我们可以使用@JvmSuppressWildcards(这可以用于包含它的类型或任何声明)
示例:
fun foo(l: List<String>) // in Java: List<String> (String is final)
fun foo(l: List<@JvmWildcard String>) // in Java: List<? extends String>
interface Open {}
fun bar(p: List<Open>) // in Java: List<? extends Open> (Open is not final)
@JvmSuppressWildcards
fun bar(p: List<Open>) // in Java: List<Open>
如果您仍然遇到问题,请将此问题应用于您的问题:
@JvmSuppressWildcards
public fun getObservable(): Observable<List<FooBar>> {
return Observable.just(theList)
}
答案 1 :(得分:3)
编辑:此行为在Kotlin Beta 4中已更改。请参阅Jayson Minard的answer。
我可以看到两个选项:
第一个是返回Observable<MutableList<FooBar>>
。由于List
在kotlin中是不可变的,因此它被声明为List<out T>
,因为类型为T的对象只能被 out 。
另一方面,MutableList
是Java的真正List
等价物:因为它是可变的,所以它被声明为MutableList<T>
。
所以你的功能是:
public fun getObservable(): Observable<MutableList<FooBar>>
= Observable.just(theList)
这个解决方案的问题在于,如果你在kotlin中使用它,你会过多地使用#34;如果您只想拥有一个不可变列表的Observable,请访问您的列表。
第二种选择是写一个&#34;代理&#34; java中的方法,一劳永逸地进行转换:
@SuppressWarnings("unchecked")
public static Observable<List<String>> _getObservable() { return (Observable) TestPackage.getObservable(); }
这很难看,但它有效,并没有打破kotlin
但是,我假设您正在使用RxJava的Observable
,那么为什么不利用这个机会在Java中强制执行kotlin的不可变列表语义?
public static Observable<List<String>> _getObservable() {
return TestPackage.getObservable().map(new Func1<List<? extends String>, List<String>>() {
@Override
public List<String> call(List<? extends String> list) {
return Collections.unmodifiableList(list);
}
});
}