0

I am looking to call the following Java method signature from Kotlin

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

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

I think in Java the standard way would be to call

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

I can't figure out how to express this in Kotlin to get this object.

I've tried

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

but this gives me the following error

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

So what is the correct way to call this method?


Update

https://stackoverflow.com/a/57016668/10039185 provided the answer how to do this.

I'm just adding two snippets with fuller Ignite specific examples of how to do this

Using unchecked cast

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

Using reified type

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)

1 Answers1

0

I think in Java the standard way would be to call

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

Because CacheConfiguration requires two type parameters, this is a raw type and not a good idea to use it. It should be

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

or

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

where KeyType and ValueType correspond to the type parameters of igniteCache. Note that the cast is necessary.

Similarly in Kotlin,

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

But you can define a helper function with reified generics:

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

and then call it as

val configuration = igniteCache.configuration<CacheConfiguration<KeyType, ValueType>>()
Community
  • 1
  • 1
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • Trying your suggestion above: `val configuration = igniteCache.getConfiguration(CacheConfiguration::class.java) as CacheConfiguration` still results in `Type mismatch: inferred type is CacheConfiguration<*, *> but Configuration! was expected` for the CacheConfiguration::class.java part of the line –  Jul 15 '19 at 18:02
  • Ok, then the cast needs to be elsewhere, try the edited version. – Alexey Romanov Jul 15 '19 at 18:33
  • The non-reified version works but has the expected warning `Unchecked cast: Class> to Class>`. The reified version removes the warning but needs to be called as `val configuration = igniteCache?.configuration>()` –  Jul 17 '19 at 22:16
  • You can use `@Suppress("UNCHECKED_CAST")` to fix the first problem (https://stackoverflow.com/questions/36221405/how-can-i-suppress-unchecked-cast-warnings) – Alexey Romanov Jul 18 '19 at 05:43