Comment passer un argument de type joker lié à Kotlin?

La classe utilisée (en Java, API tierce, non modifiable):

public class BookmarkablePageLink extends Link { public  BookmarkablePageLink(final Ssortingng id, final Class pageClass) 

Et maintenant je veux appeler ça de Kotlin:

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

bookmark.page est en Java, et il s’agit de: public Class getPage() public Class getPage()

Aucun de ces travaux:

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

Erreur: informations insuffisantes pour déduire le paramètre T dans le constructor Bookmarkable PageLink(...)

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

Ce serait la façon “hypothétiquement correcte” de faire cela en javaish (juste l’intention, mais ce n’est pas du code réel), mais ceci n’est pas supporté par Kotlin :

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

Ma meilleure solution de contournement est la suivante: elle est laide, mais elle fonctionne:

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

Étonnamment à Java, il s’agissait simplement de:

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

Je crée une réponse à partir de tous les meilleurs commentaires parce que ceux-ci semblent déjà très précieux.

La solution à la question est déjà un bon début:

 BookmarkablePageLink("link", bookmark.page as Class) 

La variable intermédiaire de @ AlexeyRomanov (ou une fonction intermédiaire similaire) est également juste:

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

Un résumé succinct de la gestion de la variance de type entre Kotlin et Java, comme expliqué dans la documentation de Kotlin, est également utile pour tous ceux qui trouvent cette question via Google:

  • en Java, le traitement s’effectue sur le site d’appels à l’aide de caractères génériques (que vous ne pouvez pas utiliser car le site d’appels se trouve dans Kotlin)
  • et dans Kotlin, le traitement est sur le site de déclaration en utilisant out mots-clés in et out (que vous ne pouvez pas utiliser, car votre déclaration est en Java)

De plus, les constructeurs Java sur call-site permettent uniquement de spécifier des arguments de type à partir de la classe, tandis que dans Kotlin, l’appel de constructeur a deux arguments de type: un de la classe et l’autre du constructeur. Donc, à Java, nous devons dire

 new BookmarkablePageLink("something", Page.class) 

et à Kotlin

 BookmarkablePageLink("something", Page::class.java) 

bien que les deux appellent le même constructeur avec les mêmes arguments.

Étant donné que Kotlin a choisi une approche pour les types de variantes qui est exactement le contraire de celle de Java, je suis toujours heureux que nous n’ayons besoin de solutions de contournement que dans très peu de cas. 😉

Pour autant que je sache, BookmarkablePageLink(...) devrait être à peu près équivalent au new BookmarkablePageLink<> en Java. Il s’agit donc de l’option “devrait” fonctionner. Tous les autres que vous avez essayés ne devraient pas, chacun pour des raisons différentes.

Les constructeurs qui ont leurs propres parameters de type sont très rares (avant de voir cette question, je pensais qu’ils étaient illégaux), ils peuvent donc être oubliés quelque part dans le compilateur Kotlin. Une solution possible consiste à en faire une fonction:

 fun  makeBookmarkablePageLink(id: Ssortingng, clazz: Class): BookmarkablePageLink = BookmarkablePageLink(id, clazz) 

et alors

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

Je vais aussi noter que je suis à peu près sûr

la “bonne” façon de faire cela en Java

est en fait faux; et en fait, vous ne pouvez pas écrire explicitement les parameters de type en Java, car le second paramètre de type est un caractère générique capturé .

S’il vous plaît essayez

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