Проблема стирания типа со ссылками на методы JavaJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Проблема стирания типа со ссылками на методы Java

Сообщение Anonymous »

Я использую Flink с Java, где столкнулся с проблемой стирания типа.
У меня есть интерфейс TransformationService, который имеет несколько реализаций, только одна из которых используется одним заданием Flink. Это определяется во время выполнения, как показано в коде ниже.
Ниже приведена подпись моей службы преобразования —

Код: Выделить всё

public interface TransformationService {
KEY keyBy(EVENT ev);
}
Вот как он используется в вызывающем коде конвейера -

Код: Выделить всё

TransformationService service = getImplementation(pipelineType);

DataStreamSource source = ...;

source
.uid("source")
.rebalance()
...
...
.keyBy(service::keyBy)
...
...

env.execute(job);
Каждая реализация TransformationService использует конкретные типы ключей и событий, которые расширяют классы Key и Event соответственно.
Пример реализации TransformationService —

Код: Выделить всё

public class LaunchEventService implements TransformationService {
LaunchEventKey keyBy(LaunchEvent event) {
...
}
}
Этот код компилируется нормально. Но при запуске этого кода я сталкиваюсь со следующей ошибкой -

Код: Выделить всё

org.apache.flink.api.common.functions.InvalidTypesException: Type of TypeVariable 'KEY' in 'interface TransformationService' could not be determined. This is most likely a type erasure problem. The type extraction currently supports types with generic variables only in cases where all variables in the return type can be deduced from the input type(s). Otherwise the type has to be specified explicitly using type information.
Я понимаю, что компилятор Java стирает фактические типы дженериков во время процесса компиляции, что может привести к тому, что среда выполнения flink не сможет определить конкретный тип ключа для некоторого конкретного класса событий.
Но при использовании следующей лямбда-функции вместо ссылки на метод в качестве параметров функции keyBy код компилируется и работает нормально -

Код: Выделить всё

TransformationService service = getImplementation(pipelineType);

DataStreamSource source = ...;

source
.uid("source")
.rebalance()
...
...
.keyBy(ev -> service.keyBy(val))
...
...

env.execute(job);
Я не могу понять разницу между этими двумя подходами и почему один работает, а другой нет. Согласно тому, что я исследовал, это связано с разницей в том, как ссылки на методы и лямбда-функции анализируются и выполняются Java, но я до сих пор не могу полностью понять этот процесс. Может кто-нибудь подробно объяснить причину, по которой это может происходить.

Подробнее здесь: https://stackoverflow.com/questions/798 ... references
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»