Kotlin中无法创建SubscribableChannel,泛型S匹配问题求助
这个问题的核心是理解Spring publishSubscribe()方法里的递归泛型约束(也叫F-bounded polymorphism):<S extends PublishSubscribeChannelSpec<S>>。简单来说,泛型参数S必须是PublishSubscribeChannelSpec的子类,并且这个子类自身的泛型参数就是它自己(比如class MySpec extends PublishSubscribeChannelSpec<MySpec>这种形式)。
最简单的解决方法:让Kotlin自动推断泛型
IntelliJ的Java转Kotlin工具有时候会多此一举地显式添加泛型参数,其实你完全可以去掉那个多余的<S>,直接写:
val c: SubscribableChannel = MessageChannels.publishSubscribe().get()
Kotlin的编译器会自动推断出符合约束的泛型类型,和Java里的运行逻辑完全一致,根本不需要手动指定类型。
如果非要显式指定泛型参数
如果你确实需要显式声明泛型,Spring内部其实有一个PublishSubscribeChannelSpec.DefaultPublishSubscribeChannelSpec类——它是PublishSubscribeChannelSpec的具体实现,完美满足S extends PublishSubscribeChannelSpec<S>的约束。不过这个类是包级私有内部类,无法直接引用。这时候可以用Kotlin的星号通配符来替代:
val c: SubscribableChannel = MessageChannels.publishSubscribe<*>().get()
不过这种写法完全没必要,自动推断的方式既简洁又易懂。
为什么Java里没问题?
Java的泛型类型推断机制可以自动处理这种递归泛型约束,不需要显式指定类型参数。而IntelliJ的转换工具可能过度“热心”地添加了泛型参数,反而导致了编译错误。
内容的提问来源于stack exchange,提问作者billdoor

