Передача значения, которое не соответствует сигнатуре метода - PullRequest
2 голосов
/ 11 июля 2019

Я использую 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 ]

1 голос
/ 11 июля 2019

Возможно, что вызывающий в вашей реализации write создает экземпляр raw типа Map.Entry. Например:

Entry entry = new Entry() { /* ... */ }
...
cache.write(entry);
1 голос
/ 11 июля 2019

В java параметры типа являются необязательными: они не переносятся вместе с экземпляром объекта и существуют только на уровне языка.

Таким образом, вы всегда можете привести к чему угодно и затем вызывать любые методы со стертыми проверками типов:

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

Что касается BinaryObjectImpl, Ignite будет пытаться поддерживать объекты в сериализованном состоянии, где это возможно, для экономии затрат на сериализацию.Поэтому вы должны знать, что параметры типа CacheStore не всегда являются типами, ориентированными на пользователя.

...