У меня есть некоторый код со ссылкой на метод, который прекрасно компилируется и не работает во время выполнения.
Исключением является следующее:
Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type class redacted.BasicEntity; not a subtype of implementation type interface redacted.HasImagesEntity
at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:233)
at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303)
at java.lang.invoke.CallSite.makeSite(CallSite.java:289)
Класс, вызывающий исключение:
class ImageController<E extends BasicEntity & HasImagesEntity> {
void doTheThing(E entity) {
Set<String> filenames = entity.getImages().keySet().stream()
.map(entity::filename)
.collect(Collectors.toSet());
}
}
Исключение выдается при попытке разрешить entity::filename
. filename()
объявлено в HasImagesEntity
. Насколько я могу судить, я получаю исключение, потому что стирание E - это BasicEntity
а JVM не рассматривает (не может?) Другие границы для E.
Когда я переписываю ссылку на метод как тривиальную лямбду, все в порядке. Мне кажется действительно подозрительным, что одна конструкция работает так, как ожидалось, и ее семантический эквивалент взрывается.
Может ли это быть в спецификации? Я очень стараюсь найти способ, чтобы это не было проблемой в компиляторе или во время выполнения, и ничего не придумали.