Search code examples
javaignitetype-parameter

Passing in a value that does not match method signature


I am using Apache Ignite, which isn't really central to the question, but gives background. In that context, I've create a class extending CacheStoreAdapter that has a method with the following signature:

@Override
public void write(Entry<? extends K, ? extends V> cacheEntry) throws CacheWriterException {

I registered that class with Ignite, so that it calls the write() method whenever I give it data to save in its cache.

What I was surprised to find is that, depending on how Ignite is otherwise configured, the following code...

final V cacheObject = cacheEntry.getValue();
LOG.info("cacheObject = " + ToStringBuilder.reflectionToString(cacheObject));

... outputs the following:

cacheObject = org.apache.ignite.internal.binary.BinaryObjectImpl@7c40ffef[ctx=org.apac

That is, the cacheObject taken from an Entry<? extends K, ? extends V> is not an instance of type V!

I've worked around the issue (as I said it only happens depending on how Ignite is otherwise configured), but I am curious how this is even done in Java.

TL;DR Question:

How is is possible to pass a variable to a method that does not conform to the method's signature? Some kind of reflection technique? Is there a common / legitimate use for doing this?


Solution

  • In java, type parameters are optional: they are not carried along with an object instance and only exist on language level.

    So you can always cast anything to and then call any methods with type checks erased:

    Map<String, Integer> sim = new HashMap<>();
    Map<Object, Object> oom = (Map<Object, Object>) (Map) sim;
    

    As for BinaryObjectImpl, Ignite will try to keep objects in serialized state where possible to save on serialization costs. So you should be aware that type parameters of CacheStore are not always the user-facing types.