Ошибка потока Java 8 в элементе JavaFX BarChart

Я получаю следующие ошибки при использовании потоков на BarChart JavaFX getData()

error: invalid method reference
                .map(XYChart.Series::getName);
                            ^ non-static method getName() cannot be referenced from a static context

 error: incompatible types: invalid method reference
                .map(XYChart.Series::getName);
                     ^ method getName in class Series<X,Y> cannot be applied to given types
      required: no arguments
      found: Object
      reason: actual and formal argument lists differ in length   where X,Y are type-variables:
    X extends Object declared in class Series
    Y extends Object declared in class Series
public class MainController{
        public BarChart barChart; // from fxml file
}

Следующий код успешно напечатает имена классов BarChart;

List<XYChart.Series> test = barChart.getData();
List<String> testList = test.stream().map(XYChart.Series::getName).collect(Collectors.toList());
System.out.println(testList);

однако этот фрагмент кода завершится ошибкой во время компиляции;

List<String> testList = barChart.getData().stream()
      .map(XYChart.Series::getName) // error line
      .collect(Collectors.toList()); 
System.out.println(testList);

Почему возникает эта ошибка и почему она возникает только в первом примере, но не во втором? В чем разница между этими двумя примерами кода?

[запускать с Gradle и версией Java 1.8.0_144]

Это происходит потому, что вы не указали общий тип BarChart (формальное объявление для которого - BarChart<X extends Object, Y extends Object>. Последний пример, в частности, приведет к компиляции предупреждение, что-то вроде предупреждения о "небезопасном приведении".

M. Prokhorov 17.04.2018 13:49

Спасибо за ваш вклад, я обновил свой код.

helloworld 17.04.2018 14:03

Объявление List<XYChart.Series> test выдаст предупреждение, если вы явно не подавите его в своей среде IDE. Ссылки на методы разрешаются компилятором в зависимости от типов используемых ссылок. Разрешение ссылок на методы - сложный, потому что существует много разных возможностей их разрешения. Если вы используете необработанные типы, вы рискуете не предоставить компилятору достаточно информации для разрешения ссылки на метод.

James_D 17.04.2018 14:15

Я не знаю точно, почему первая версия не выдает ошибку, а вторая - но подозреваю, что явный ввод результата barChart.getData(), поскольку List<XYChart.Series> приводит к тому, что компилятор неявно присваивает ему тип List<XYChart.Series<Object,Object>>, которого достаточно для ссылка на метод для разрешения. Во второй версии, поскольку barChart имеет необработанный тип, недостаточно информации для разрешения ссылки на метод, потому что результат barChart.getData() никогда не имеет допустимого типа (необработанный или нет).

James_D 17.04.2018 14:18

Суть в том, что вам просто не следует использовать необработанные типы: нет абсолютно никаких причин для этого, если вы не взаимодействуете с устаревшим (до Java 5) кодом, что не так, если вы используете JavaFX 8 или новее. (Так что, по сути, вам все равно, почему первое не выдает ошибок, а второе - ошибку: вам просто не следует писать этот код в первую очередь.)

James_D 17.04.2018 14:19

@James_D большое спасибо, теперь я понял :)

helloworld 17.04.2018 14:21

@James_D небольшая поправка. BarChart необработанного типа getData() имеет допустимый тип, это необработанный тип ObservableList, метод stream() которого возвращает необработанный тип Stream. Конечно, не зная типа элемента, вы не можете использовать .map(XYChart.Series::getName), который требует, чтобы элементы были типа XYChart.Series. В первой версии присвоение List<XYChart.Series> уже является преобразованием не отмечен из необработанного типа ObservableList в List<XYChart.Series>. И необработанный тип XYChart.Series - это нет, то же самое, что и XYChart.Series<Object,Object>.

Holger 18.04.2018 09:05
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
7
76
0

Другие вопросы по теме