【问题标题】:How to call Java method expecting a parameter which is a class with generics in Kotlin如何调用期望参数的Java方法,该参数是Kotlin中具有泛型的类
【发布时间】:2019-07-18 06:27:10
【问题描述】:

我希望从 Kotlin 调用以下 Java 方法签名

    <C extends javax.cache.configuration.Configuration<K,V>> C getConfiguration(Class<C> clazz)

来自https://ignite.apache.org/releases/2.7.5/javadoc/org/apache/ignite/IgniteCache.html#getConfiguration-java.lang.Class-

我认为在 Java 中标准方式是调用

    CacheConfiguration configuration = igniteCache.getConfiguration(CacheConfiguration.class);

我不知道如何在 Kotlin 中表达这个来获取这个对象。

我试过了

   val configuration = igniteCache.getConfiguration(CacheConfiguration::class.java)

但这给了我以下错误

    Type mismatch: inferred type is CacheConfiguration<*, *> but Configuration<K!, V!>! was expected

那么调用这个方法的正确方法是什么?


更新

https://stackoverflow.com/a/57016668/10039185 提供了如何做到这一点的答案。

我只是添加了两个带有更完整的 Ignite 具体示例的 sn-ps,以说明如何执行此操作

使用未经检查的演员表

private fun <K, V> checkCacheUsingUncheckedCast(igniteCache: IgniteCache<K, V>?) {
    val configuration = igniteCache?.getConfiguration(CacheConfiguration::class.java as Class<CacheConfiguration<K, V>>)
    if (configuration != null) {
        // do something with the configuration
    }
}

使用具体化类型

private fun <K, V> checkCacheUsingReifiedType(igniteCache: IgniteCache<K, V>?) {
    val configuration = igniteCache?.configuration<K, V, CacheConfiguration<K, V>>()
    if (configuration != null) {
        // do something with the configuration
    }
}

private inline fun <K, V, reified C : Configuration<K, V>> IgniteCache<K, V>.configuration() = getConfiguration(C::class.java)

【问题讨论】:

    标签: generics kotlin ignite


    【解决方案1】:

    我认为在 Java 中标准方式是调用

    CacheConfiguration configuration = igniteCache.getConfiguration(CacheConfiguration.class);
    

    因为CacheConfigurationrequires two type parameters,这是raw type,使用它不是一个好主意。应该是

    CacheConfiguration<KeyType, ValueType> configuration = (CacheConfiguration<KeyType, ValueType>) igniteCache.getConfiguration(CacheConfiguration.class);
    

    var configuration = (CacheConfiguration<KeyType, ValueType>) igniteCache.getConfiguration(CacheConfiguration.class);
    

    其中KeyTypeValueType对应igniteCache的类型参数。请注意,演员表是必要的。

    在 Kotlin 中也是如此,

    val configuration = igniteCache.getConfiguration(CacheConfiguration::class.java as Class<CacheConfiguration<KeyType, ValueType>>)
    

    但是你可以用reified generics定义一个辅助函数:

    inline fun <K, V, reified C : Configuration<K, V>> IgniteCache<K, V>.configuration() = getConfiguration(C::class.java)
    

    然后将其称为

    val configuration = igniteCache.configuration<CacheConfiguration<KeyType, ValueType>>()
    

    【讨论】:

    • 在上面尝试你的建议:val configuration = igniteCache.getConfiguration(CacheConfiguration::class.java) as CacheConfiguration&lt;String, String&gt; 仍然会导致 Type mismatch: inferred type is CacheConfiguration&lt;*, *&gt; but Configuration&lt;K!, V!&gt;! was expected 用于该行的 CacheConfiguration::class.java 部分
    • 好的,那么演员需要在别处,试试修改后的版本。
    • 未具体化的版本有效,但有预期的警告Unchecked cast: Class&lt;CacheConfiguration&lt;*, *&gt;&gt; to Class&lt;CacheConfiguration&lt;K, V&gt;&gt;。实体化版本去掉了警告但需要调用为val configuration = igniteCache?.configuration&lt;K, V, CacheConfiguration&lt;K, V&gt;&gt;()
    • 可以使用@Suppress("UNCHECKED_CAST")修复第一个问题(stackoverflow.com/questions/36221405/…
    猜你喜欢
    • 2023-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多