将匿名类(实现一种方法)重构为lambda表达式,可使您的代码更简洁明了。 例如,这是Runnable
及其lambda等效项的匿名类:
// using an anonymous class
Runnable r = new Runnable() {@Overridepublic void run() {System.out.println("Hello");}
};// using a lambda expression
Runnable r2 = () -> System.out.println("Hello");
但是,它并不总是那么简单!
这里有一些陷阱:
1.不同的作用域规则
匿名类和lambda表达式之间有不同的作用域规则。 例如,在lambda表达式中, this
和super
在词法上是作用域的,这意味着它们是相对于封闭类的,而在匿名类中,它们是相对于匿名类本身的。 同样,在lambda表达式中声明的局部变量将与在封闭类中声明的变量发生冲突,但是在匿名类中,允许它们在封闭类中对变量进行屏蔽 。 这是一个例子:
int foo = 1;
Runnable r = new Runnable() {@Overridepublic 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.重载方法
如果您有重载的方法,则使用lambda表达式可能会导致方法调用不明确,并且需要显式转换。 这是一个例子:
// Functional interface
interface Task {public void execute();
}// Overloaded methods
public 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 instantiation
go(new Task() {@Overridepublic void execute() {System.out.println("Hello");}
});// When using a lambda expression, there is a compile error!
// The method go(Runnable) is ambiguous
go(() -> {System.out.println("Hello");
});// This ambiguity can be solved with an explicit cast
go((Task)() -> {System.out.println("Hello");
});
翻译自: https://www.javacodegeeks.com/2016/06/java-8-converting-anonymous-classes-lambda-expressions.html