Сообщение об ошибке появляется также в Eclipse-IDE:
Тип выражения должен быть типом массива, но оно разрешено в Object
Я думаю, что этоне является ошибкой IDE, ни в IntelliJ, ни в Eclipse.Компилятору нужен для обработки лямбда-выражения всегда тип цели , который является функциональным интерфейсом.В случае
args -> instance.getAttribute((int)args[0].value())
целевой тип определяется первым аргументом конструктора Func
Function<Var[], Var<T>> function
Однако этот функциональный интерфейс является универсальным интерфейсом.Java компилирует обобщенные типы, используя стирание типа , что означает замену обобщенных типов параметров типом объекта.Таким образом, интерфейс компилируется как
interface Function {
public Object apply(Object args);
}
, и это применяется в качестве целевого типа.Таким образом, для аргументов ожидается тип Object вместо типа Var [], что приведет к сообщению об ошибке.
В случае анонимного класса это не так, поскольку для определениятип цели
new Function<Var[], Var>(){...}
явно содержит информацию о типе.Из-за этого ожидаются аргументы типа Var [], и сообщение об ошибке не отображается.
Существует две возможности исправить ошибку:
1) В методе getAttribut приводить аргументы явнона Var [], т.е. замените
(int)args[0].value()
на
(int)((Var[])args)[0].value()
или 2) Не используйте универсальный интерфейс, т.е. измените интерфейс на
interface Function {
public Var apply(Var[] args);
}
Тогда информация о типе сохраняется.Конечно, остальная часть кода должна быть соответствующим образом адаптирована.