如何在Kotlin中传递有界通配符类型参数?

时间:2018-05-19 12:59:58

标签: java generics kotlin wicket wildcard

使用的类(在Java中,第三方API,不可更改):

public class BookmarkablePageLink<T> extends Link<T> {

    public <C extends Page> BookmarkablePageLink(final String id, final Class<C> pageClass)

现在我想从Kotlin那里打电话:

item.queue(BookmarkablePageLink("link", bookmark.page))

bookmark.page在Java中,它是:public Class<? extends WebPage> getPage()

这些都不起作用:

item.queue(BookmarkablePageLink("link", bookmark.page))
  

错误:没有足够的信息来推断constructor Bookmarkable PageLink<T : Any!, C : Page!>(...)

中的参数 T
item.queue(BookmarkablePageLink<>("link", bookmark.page))

item.queue(BookmarkablePageLink<Any>("link", bookmark.page))

item.queue(BookmarkablePageLink<Any, *>("link", bookmark.page))

item.queue(BookmarkablePageLink<Any, WebPage>("link", bookmark.page))

item.queue(BookmarkablePageLink<Any, in WebPage>("link", bookmark.page))

item.queue(BookmarkablePageLink<Any, out WebPage>("link", bookmark.page))

item.queue(BookmarkablePageLink<Any, T : WebPage>("link", bookmark.page))

这将是假设正确的&#34;用Javaish语言表达的方式(只是意图,但它不是真正的代码),但是this isn't supported by Kotlin

item.queue(BookmarkablePageLink<Any, ? extends WebPage>("link", bookmark.page))

我最好的解决方法就是这个,这很难看,但有效:

item.queue(BookmarkablePageLink<Any, WebPage>("link", bookmark.page as Class<WebPage>))

令人惊讶的是,在Java中,这只是:

item.queue(new BookmarkablePageLink<>("link", bookmark.getPage() ));

2 个答案:

答案 0 :(得分:3)

我正在从所有最好的评论中找到答案,因为那些看起来非常有价值。

问题的解决方法已经是一个良好的开端:

BookmarkablePageLink<Any, WebPage>("link", bookmark.page as Class<WebPage>)

同样公平的是@AlexeyRomanov的中间变量(或类似的中间函数):

val link: BookmarkablePageLink<Any> = BookmarkablePageLink("link", bookmark.page)

对于通过Google发现此问题的所有人来说,也很有价值可能是Kotlin与Java处理类型差异的简短摘要,如Kotlin's documentation中所述:

  • 在Java中,使用通配符处理呼叫站点(您无法使用,因为呼叫站点位于Kotlin中)
  • 并且在Kotlin中,使用inout关键字(您无法使用,因为您的声明是使用Java)在声明网站处理

此外,call-site的Java构造函数只允许从类中指定类型参数,而在Kotlin中,构造函数调用有两个类型参数:一个来自类,另一个来自构造函数。 所以在Java中,我们不得不说

new BookmarkablePageLink<T>("something", Page.class)

和Kotlin

BookmarkablePageLink<T, Page>("something", Page::class.java)

尽管都使用相同的参数调用相同的构造函数。

鉴于Kotlin为变体类型选择了一种与Java完全相反的方法,我仍然很高兴,我们只需要在极少数情况下需要解决方法。 ; - )

答案 1 :(得分:2)

请尝试

item.queue(BookmarkablePageLink<Any, WebPage>("link", bookmark.page))