Рефакторинг анонимных классов (которые реализуют один единственный метод) в лямбда-выражения делает ваш код более лаконичным и читабельным. Например, вот анонимный класс для Runnable и его лямбда-эквивалент:
|
01
02
03
04
05
06
07
08
09
10
|
// using an anonymous classRunnable r = new Runnable() { @Override public void run() { System.out.println("Hello"); }};// using a lambda expressionRunnable r2 = () -> System.out.println("Hello"); |
Однако это не всегда так просто!
Вот несколько ошибок:
1. Различные правила определения объема
Существуют разные правила определения объема между анонимными классами и лямбда-выражениями. Например, в лямбда-выражениях this и super имеют лексическую область видимости, то есть они относятся к включающему классу, но в анонимном классе они относятся к самому анонимному классу. Точно так же локальные переменные, объявленные в лямбда-выражениях, будут конфликтовать с переменными, объявленными в классе включения, но в анонимных классах им разрешено скрывать переменные в классе включения. Вот пример:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
int foo = 1;Runnable r = new Runnable() { @Override public void run() { // this is ok! int foo = 2; }};Runnable r2 = () -> { // compile error: Lambda expression's local variable foo cannot // redeclare another local variable defined in an enclosing scope. int foo = 2;}; |
2. Перегруженные методы
Если у вас перегруженный метод, использование лямбда-выражений может привести к неоднозначному вызову метода и потребует явного приведения. Вот пример:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
// Functional interfaceinterface Task { public void execute();}// Overloaded methodspublic static void go(final Runnable r) { r.run();}public static void go(final Task t) { t.execute();}// Calling the overloaded method:// When using an anonymous class, there is no ambiguity because// the type of the class is explicit at instantiationgo(new Task() { @Override public void execute() { System.out.println("Hello"); }});// When using a lambda expression, there is a compile error!// The method go(Runnable) is ambiguousgo(() -> { System.out.println("Hello");});// This ambiguity can be solved with an explicit castgo((Task)() -> { System.out.println("Hello");}); |
| Ссылка: | Java 8: преобразование анонимных классов в лямбда-выражения от нашего партнера по JCG Фахда Шарифа в блоге fahd.blog . |