传递与方法签名不匹配的值

时间:2019-07-11 14:41:21

标签: java ignite type-parameter

我正在使用Apache Ignite,它并不是该问题的核心,但提供了背景信息。在这种情况下,我创建了一个扩展CacheStoreAdapter的类,该类具有带有以下签名的方法:

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

我在Ignite上注册了该类,因此每当我给它提供要保存在其缓存中的数据时,它就会调用write()方法。

我很惊讶地发现,根据Ignite的配置方式,以下代码...

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

...输出以下内容:

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

也就是说,从cacheObject提取的Entry<? extends K, ? extends V>不是类型V的实例!

我已经解决了这个问题(正如我所说的,这仅取决于Ignite的配置方式),但我很好奇这在Java中是如何完成的。

TL; DR问题:

如何将变量传递给不符合方法签名的方法?某种反射技术?

2 个答案:

答案 0 :(得分:1)

在Java中,类型参数是可选的:它们不随对象实例一起携带,仅存在于语言级别。

因此,您始终可以将任何内容强制转换为任何类型,然后调用已删除类型检查的任何方法:

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

对于BinaryObjectImpl,Ignite将尝试将对象保持序列化状态,以尽可能节省序列化成本。因此,您应该意识到CacheStore的类型参数并不总是面向用户的类型。

答案 1 :(得分:1)

实现write的调用者可能会创建raw type Map.Entry的实例。例如:

Entry entry = new Entry() { /* ... */ }
...
cache.write(entry);