Функциональный интерфейс - это не что-то техническое, что реализуется в языке или виртуальной машине. Это просто абстракция, которая была в Java всегда.
Java задумывалась как исключительно объектно ориентированный язык, поэтому функций в ней никогда не было и нет. Всё
поведение располагается в методах. Но для обработчиков событий, например, нужно только поведение, но не состояние, поэтому объект "оборачивающий" метод бесполезен. Обычно обработчик выглядел так:
someButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
someTextField.setText("Кнопка нажата");
}
});
ActionListener имеет функциональный интерфейс. То есть интерфейс с одним методом, как бы заявляющий "я не класс, я функция".
В Java 8 просто появились способы более удобно работать с функциональными интерфейсами - в языке появились лямбды, у виртуальной машины появились средства, позволяющие генерировать из лямбд классы с функциональным интерфейсом, а в стандартной библиотеке появился пакет java.util.function, содержащий набор универсальных функциональных
интерфейсов, позволяющих передавать и возвращать лямбды между методами в коде разных разработчиков.