上下文与作用域
上下文
Assignment Context
在赋值运算符的右边可以出现一个
public class Main {
public static void main(String[] argv) {
Calculator iCal = (x,y)-> x + y;//from www.j a v a 2s .c o m
System.out.println(iCal.calculate(1, 2));
}
}
@FunctionalInterface
interface Calculator{
int calculate(int x, int y);
}
Method Invocation Context
我们可以使用
public class Main {
public static void main(String[] argv) {
engine((x,y)-> x / y);// www . j a v a2s . co m
}
private static void engine(Calculator calculator){
long x = 2, y = 4;
long result = calculator.calculate(x,y);
System.out.println(result);
}
}
@FunctionalInterface
interface Calculator{
long calculate(long x, long y);
}
Return Context
我们可以在返回语句中使用
public class Main {
public static void main(String[] argv) {
System.out.println(create().calculate(2, 2));
}// ww w .j a v a2s . com
private static Calculator create(){
return (x,y)-> x / y;
}
}
@FunctionalInterface
interface Calculator{
long calculate(long x, long y);
}
Cast Context
我们可以使用一个
public class Main {
public static void main(String[] argv) {
engine((IntCalculator) ((x,y)-> x + y));
}
private static void engine(IntCalculator calculator){
int x = 2, y = 4;
int result = calculator.calculate(x,y);
System.out.println(result);
}
private static void engine(LongCalculator calculator){
long x = 2, y = 4;
long result = calculator.calculate(x,y);
System.out.println(result);
}
}
@FunctionalInterface
interface IntCalculator{
int calculate(int x, int y);
}
@FunctionalInterface
interface LongCalculator{
long calculate(long x, long y);
}
Variable Scope | 变量作用域
在
- 本地变量
(Local Variable) 可以访问但是不可以修改。 - 类成员变量与静态变量可以被读写,即闭包中的
this 实际指向的是创建该Lambda 表达式的方法的this 参数。 - 函数式接口的默认方法不可以在
Lambda 表达式中被访问。
局部变量
Path first = Paths.get("/usr/bin");
Comparator<String> comp = (first,second) ->
Integer.compare(first.length(),second.length());
//错误,变量first已经定义了
在一个方法里,你不能有两个同名的局部变量,因此,你也不能在
public class T1 {
public static void main(String[] args) {
repeatMessage("Hello", 20);
}
public static void repeatMessage(String text, int count) {
Runnable r =
() -> {
for (int i = 0; i < count; i++) {
System.out.println(text);
Thread.yield();
}
};
new Thread(r).start();
}
}
this
当你在
public class Application {
public void doWork() {
Runnable runner =
() -> {
System.out.println(this.toString());
};
}
}
表达式
引用的变量不可更改
public static void repeatMessage(String text,int count){
Runnable r = () -> {
while(count > 0){
count--; //错误,不能更改已捕获变量的值
System.out.println(text);
Thread.yield();
}
};
new Thread(r).start();
}
做出这个约束是有原因的。更改
int matches = 0;
for(Path p : files)
new Thread(() -> {if(p中包含某些属性) matches++;}).start(); //非法更改matches的值
如果这段代码是合法的,那么会引起十分糟糕的结果。自增操作
List<Path> matches = new ArrayList<>();
for(Path p: files)
// 你可以改变matches的值,但是在多线程下是不安全的
new Thread(() -> {if(p中包含某些属性) matches.add(p);}).start();
注意