使用的类(在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()

None of these work:

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

Error: Not enough information to infer parameter T in constructor Bookmarkable PageLink<T : Any!, C : Page!>(...)

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))

This would be the "hypothetically correct" way to do this in Javaish-speak (just the intention, but it's not real code), but 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>))

Surprisingly in Java this was simply:

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

推荐答案

I am creating a answer from all the best comments because those already seem very valuable.

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

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

Also fair is @AlexeyRomanov's intermediate variable (or a similar intermediate function):

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

对于所有通过谷歌找到这个问题的人来说,同样有价值的可能是Kotlin vs Java处理类型差异的简短总结,如Kotlin's documentation中所述:

  • 在Java中,处理是在调用站点使用通配符(不能使用通配符,因为调用站点位于Kotlin中)
  • 在Kotlin中,处理是在声明站点使用inout个关键字(您不能使用,因为您的声明是Java的)

Additionally, Java constructors at call-site only allow to specify type arguments from the class, while in Kotlin the constructor call has two type arguments: one from the class and the other from the constructor. So in Java, we have to say

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

and in Kotlin

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

尽管两者都使用相同的参数调用相同的构造函数.

Given that Kotlin chose an approach for variant types which is the exact opposite of Java's, I am still happy, that we only need workarounds in so few cases. ;-)

Kotlin相关问答推荐

为什么在Spring中,对事务性方法调用的非事务方法调用仍然在事务中运行?

"Kotlin中的表达式

Kotlin:类型不匹配:推断的类型已运行,但应等待

数据流弹性模板失败,出现错误&未知非复合转换urn";

为什么Kotlin有次构造函数和init块?

始终抛出的函数 - 具有块主体的函数中需要的返回表达式

如何从 var list 或可变列表中获取列表流

如何使用成员引用在 Kotlin 中创建属性的分层路径

如何在 Kotlin 中将with代码转换为完整代码?

如何从kotlin中的ArrayList中删除所有元素

有没有办法重用 Job 实例?

Kotlin 中的部分类委托

调用单元测试验证伴随对象方法

Jacoco在Gradle 7.0.2和Kotlin 1.5.10上失败

类型不匹配:推断类型为 LoginActivity 但应为 LifecycleOwner

重复构建失败To use Coroutine features, you must add `ktx`......

IllegalStateException:function = , count = 3, index = 3

保存对象时未填充 Spring Boot JPA@CreatedDate @LastModifiedDate

通过在 kotlin-gradle 中使用子项目Unresolved reference: implementation

Android Jetpack Compose - 图像无法zoom 到框的宽度和高度