Я получаю следующие ошибки при использовании потоков на 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]
Спасибо за ваш вклад, я обновил свой код.
Объявление List<XYChart.Series> test выдаст предупреждение, если вы явно не подавите его в своей среде IDE. Ссылки на методы разрешаются компилятором в зависимости от типов используемых ссылок. Разрешение ссылок на методы - сложный, потому что существует много разных возможностей их разрешения. Если вы используете необработанные типы, вы рискуете не предоставить компилятору достаточно информации для разрешения ссылки на метод.
Я не знаю точно, почему первая версия не выдает ошибку, а вторая - но подозреваю, что явный ввод результата barChart.getData(), поскольку List<XYChart.Series> приводит к тому, что компилятор неявно присваивает ему тип List<XYChart.Series<Object,Object>>, которого достаточно для ссылка на метод для разрешения. Во второй версии, поскольку barChart имеет необработанный тип, недостаточно информации для разрешения ссылки на метод, потому что результат barChart.getData() никогда не имеет допустимого типа (необработанный или нет).
Суть в том, что вам просто не следует использовать необработанные типы: нет абсолютно никаких причин для этого, если вы не взаимодействуете с устаревшим (до Java 5) кодом, что не так, если вы используете JavaFX 8 или новее. (Так что, по сути, вам все равно, почему первое не выдает ошибок, а второе - ошибку: вам просто не следует писать этот код в первую очередь.)
@James_D большое спасибо, теперь я понял :)
@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>.




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