10. Анонимные классы, интерфейсы, методы. Лямбда-выражения
При создании объектов с помощью оператора new возвращается ссылка на вновь созданный объект. Однако нас никто не обязывает эту ссылку присваивать в качестве значения ссылочной переменной. В таких случаях создается анонимный объект. Другими словами, объект есть, а переменной, которая бы содержала ссылку на этот объект, нет.
С практической точки зрения это может выглядеть бесполезным, однако, анонимные объекты требуются довольно часто - обычно в тех ситуациях, когда объект класса используется один раз. Рассмотрим пример:
В данном случае, нам нужен объект класса PrintManager
только для одного действия - для распечатки файла. То есть, мы создаем объект, вызываем метод, после чего объект нам больше не нужен.
В таких случаях удобно использовать анонимные объекты.
В первом случае используется обычный порядок работы с объектами - создаем объект класса PrintManager
, ссылка на объект записывается в ссылочную переменную manager.
Во втором случае мы создаем анонимный объект. Инструкция
выполняется следующим образом. Сначала создается новый объект класса PrintManager
, оператор new возвращает ссылку на созданный объект. После чего, мы вызываем метод printFile()
с аргументом file
.
В третьем случае, мы в качестве аргумента метода printFile()
передаем анонимный объект класса File
. В этом случае, ссылку на объект класса File
будет хранить параметр метода printFile()
внутри тела метода.
Анонимные классы
Механизм анонимных классов позволяет объявить класс и сразу создать его экземпляр. Это позволяет сделать код кратким и выразительным. Анонимные классы удобно использовать, если класс нужен единожды.
Основная особенность - анонимный класс не имеет имени. Анонимный класс может быть подклассом существующего класса или реализацией интерфейса.
Особенности анонимного класса:
нет явного конструктора;
к анонимному классу невозможно обратиться извне объявляющего его выражения;
анонимные классы не могут быть статическими;
анонимный класс всегда конечен (
final
);каждое объявление анонимного класса уникально.
В примере ниже объявлены два анонимный класса, которые являются подклассами PrintManager
. Оба анонимных класса являются разными уникальными классами.
Анонимные методы (лямбда-выражения)
Из-за особенностей реализации лямбда-выражений в Java, дальнейшая информация по поводу лямбда-выражений справедлива только для языка Java.
Лямбда-выражение - это анонимный метод, то есть метод без названия. Такой метод выполняется не самостоятельно, а служит для реализации функционального интерфейса. Таким образом, лямбда-выражение приводит к некоторой форме анонимного класса.
Функциональный интерфейс - интерфейс, который содержит один и только один абстрактный метод. Как правило, такой метод определяет предполагаемое назначение интерфейса. Следовательно, функциональный интерфейс представляет единственное действие. К функциональным интерфейсам можно отнести, например, интерфейс ActionListener.
Лямбда-выражения позволяют объявить метод и сразу же использовать его. Это полезно в случаях однократного вызова метода, так как сокращает время на объявление и написание метода без необходимости создавать отдельный класс. Лямбда-выражение в Java имеет следующий синтаксис:
Лямбда-выражение вносит новый элемент в синтаксис и оператор в язык Java. Этот новый оператор называется лямбда-оператором, или операцией "стрелка" ->
. Он разделяет лямбда-выражение на две части. В левой части указываются любые параметры, требующиеся в лямбда-выражении (если параметры не требуются, то они указываются пустым списком). А в правой части находится тело лямбда-выражения, где указываются действия, выполняемые лямбда-выражением. Операция ->
буквально означает "становиться" или "переходить".
В Java определены две разновидности тел лямбда-выражений. Одна из них состоит из единственного выражения (одиночное выражение), а другая - из блока кода (блочное выражение).
Одиночное лямбда-выражение.
Для начала рассмотрим самое простое лямбда-выражение. Это будет выражение, которое не принимает никаких параметров, а возвращает константу. Также объявим метод, который аналогичен лямбда-выражению.
Приведем еще один пример уже более полезного выражения
Как вам понятно, лямбда-выражение возвращает псевдослучайное значение, умноженное на 100.
Два первых примера не принимают никаких параметров. Если же вам необходимо передать параметры, они указываются списком в левой части лямбда-оператора.
Тип параметров можно указывать явно, но зачастую в этом нет необходимости, потому что тип параметров выводится.
Блочные лямбда-выражения
Предыдущие примеры содержали в теле выражения лишь одно выражение. Мы уже знаем, что такие лямбда-выражения называются одиночными.
Но ничего вам не мешает создавать блочные лямбда-выражения, которые в теле содержат блок выражений. В таком блоке можно создавать циклы, ветвления - все как в обычном блоке выражений.
При создании блочного выражения необходимо явно указать оператор return
.
Лямбда-выражение как реализация интерфейса
Как было упомянуто ранее, в Java 8 было введено понятие функционального интерфейса - интерфейса с одним абстрактным методом. Лямбда-выражение не существует самостоятельно, а реализует абстрактный метод, определенный в функциональном интерфейсе.
Таким образом, лямбда может быть указана в том контексте, в котором определен ее целевой тип. Один из таких контекстов создается в том случае, когда лямбда присваивается ссылке на функциональный интерфейс. К числу других контекстов целевого типа относится инициализация переменных, оператор return и аргументы методов.
Last updated
Was this helpful?