携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第27天,点击查看活动详情
继续......Lambda 表达式,之前,整理了几次了,都没有涉及完全,今天继续,主要整理一下 Lambda 表达式的作用域......冲......
Lambda 表达式的作用域
Lambda 表达式可以看作是匿名内部类实例化的对象,Lambda 表达式对变量的访问限制和匿名内部类一样,因此 Lambda 表达式可以访问局部变量、局部引用、静态变量、实例变量。
访问局部变量
在 Lambda 表达式中,规定 只能引用标记了 final 的外层局部变量。不能在 Lambda 内部修改定义在域外的局部变量,否则会编译错误。
public class TestFinalVariable {
interface TestInterface {
Integer change(String str);
}
public static void main(String[] args) {
//局部变量未使用 final 修饰
Integer testInt = 1;
TestInterface testInterface = (str -> Integer.valueOf(str + testInt));
//再次修改,不符合隐式 final 定义
testInt = 2;
Integer testStr = testInterface.change("cgx");
System.out.println(testStr);
}
}
上述代码会出现编译报错,错误类似 Error:(XX, XX) java:从lambda表达式引用的本地变量必须是最终变量或实际上的最终变量
特殊情况,局部变量也可以不用 final 修饰,但是必须不可被后面的代码修改(即隐性的具有 final 的特性)
将上述代码改造,确保 Lambda 表达式后局部变量不做修改,就不会编译报错了:
public class TestFinalVariable {
interface TestInterface {
Integer change(String str);
}
public static void main(String[] args) {
//局部变量未使用 final 修饰
Integer testInt = 1;
TestInterface testInterface = (str -> Integer.valueOf(str + testInt));
Integer testStr = testInterface.change("cgx");
System.out.println(testStr);
}
}
访问局部变量、静态变量、实例变量
Lambda 表达式不限制访问局部引用变量、静态变量、实例变量:
public class TestOtherVariable {
//静态变量
private static String staticVar;
// 实例变量
private static String instanceVar;
@FunctionalInterface
interface VarChangeInterface{
Integer change(String str);
}
//测试引用变量
private void testReferenceVar(){
ArrayList<String> list = new ArrayList<>();
list.add("111");
//访问外部引用局部引用变量
VarChangeInterface varChangeInterface = ((str) -> Integer.valueOf(list.get(0)));
//修改局部引用变量
list.set(0,"222");
Integer str =varChangeInterface.change("");
System.out.println(str);
}
//测试静态变量
void testStaticVar(){
staticVar="222";
VarChangeInterface varChangeInterface = (str -> Integer.valueOf(str+staticVar));
staticVar="333";
Integer str =varChangeInterface.change("111") ;
System.out.println(str);
}
//测试实例变量
void testInstanceVar(){
instanceVar="222";
VarChangeInterface varChangeInterface = (str -> Integer.valueOf(str+instanceVar));
instanceVar="333";
Integer str =varChangeInterface.change("111") ;
System.out.println(str);
}
public static void main(String[] args) {
new TestOtherVariable().testReferenceVar();
new TestOtherVariable().testStaticVar();
new TestOtherVariable().testInstanceVar();
}
}
结果:
222
111333
111333
注意:Lambda 表达式中不允许声明一个与局部变量同名的参数或局部变量:
Integer testInt = 1;
VarTestInterface varTest1 = (testInt -> Integer.valueOf(testInt));
VarTestInterface varTest2 = (str -> {
Integer testInt = 1;
Integer.valueOf(str);
});
上述代码中 testInt 声明时重名,会编译报错!
每天稍微整理一点,太多了也怕消化不了[doge],明天继续......
希望本文能够帮到你,如有错误,望指正!
我向你敬礼啊,Salute!