如果将Java匿名内部类转换为Lambda表达式,范围会发生什么变化?

如果将Java匿名内部类转换为Lambda表达式,范围会发生什么变化?,java,lambda,scope,Java,Lambda,Scope,发件人: “…[匿名内部类]引入了一个新的作用域。也就是说,名称是从AIC的超类和接口解析的,并且可以隐藏在词汇封闭环境中出现的名称。对于lambda,所有名称都是按照词汇解析的。” 鉴于上述关于作用域的陈述,如果Java匿名内部类简单地转换为Lambda,执行方式会有所不同吗? 这两段代码看起来行为相同: button.addClickHandler(clickEvent -> doSomething()); 及 但是如果内部方法改为doSomething(this),情况会

发件人:
“…[匿名内部类]引入了一个新的作用域。也就是说,名称是从AIC的超类和接口解析的,并且可以隐藏在词汇封闭环境中出现的名称。对于lambda,所有名称都是按照词汇解析的。”

鉴于上述关于作用域的陈述,如果Java匿名内部类简单地转换为Lambda,执行方式会有所不同吗?

这两段代码看起来行为相同:

    button.addClickHandler(clickEvent -> doSomething());

但是如果内部方法改为
doSomething(this)
,情况会是这样吗?或
doSomething(myVariable)

如果能举一个例子,说明范围的变化很重要,以及它的行为方式,那将是非常棒的。我知道lambda在其他方面与匿名内部类不同,但我还没有找到任何好的解释来解释范围的这种变化。

From:
当在内部类的实例中使用时,您引用的是内部类的实例。lambda表达式不是内部类,这不是引用lambda表达式的实例。它引用的是定义lambda表达式的类的实例。在您的情况下,它将是Main的实例。但由于您的方法是静态的,因此没有实例。“

因此,由于Lambda不是一个内部类,而是一个方法,Lambda函数的作用域将是封闭类的作用域,而不是Lambda(匿名内部类的情况就是这样)。

From:
当在内部类的实例中使用时,您引用的是内部类的实例。lambda表达式不是内部类,这不是引用lambda表达式的实例。它引用的是定义lambda表达式的类的实例。在您的情况下,它将是Main的实例。但由于您的方法是静态的,因此没有实例。“


因此,由于Lambda不是一个内部类,而是一个方法,因此Lambda函数的作用域将是封闭类的作用域,而不是Lambda(匿名内部类的情况就是如此)。

考虑以下示例:

import java.util.function.Function;

public class Main {
    private static abstract class ParentClass implements Function<String, String> {
        protected String prefix = "parent_class_";
    }

    public static void main(String... args) {
        String prefix = "local_";
        printString("test", new ParentClass() {
            @Override
            public String apply(String s) {
                return prefix + s;
            }
        });
        printString("test", s -> prefix + s);
    }

    private static void printString(String baseString, Function<String, String> stringMapper) {
        System.out.println(stringMapper.apply(baseString));
    }
}
import java.util.function.function;
公共班机{
私有静态抽象类ParentClass实现函数{
受保护的字符串前缀=“父类”;
}
公共静态void main(字符串…参数){
字符串前缀=“本地”;
printString(“测试”,新父类(){
@凌驾
公共字符串应用(字符串s){
返回前缀+s;
}
});
打印字符串(“测试”,s->前缀+s);
}
私有静态void打印字符串(字符串基串、函数stringMapper){
System.out.println(stringMapper.apply(baseString));
}
}
这张照片

家长考试

局部检验


特别是,AIC中的
前缀
表示父类中的字段,而lambda中的
前缀
表示局部变量。

考虑以下示例:

import java.util.function.Function;

public class Main {
    private static abstract class ParentClass implements Function<String, String> {
        protected String prefix = "parent_class_";
    }

    public static void main(String... args) {
        String prefix = "local_";
        printString("test", new ParentClass() {
            @Override
            public String apply(String s) {
                return prefix + s;
            }
        });
        printString("test", s -> prefix + s);
    }

    private static void printString(String baseString, Function<String, String> stringMapper) {
        System.out.println(stringMapper.apply(baseString));
    }
}
import java.util.function.function;
公共班机{
私有静态抽象类ParentClass实现函数{
受保护的字符串前缀=“父类”;
}
公共静态void main(字符串…参数){
字符串前缀=“本地”;
printString(“测试”,新父类(){
@凌驾
公共字符串应用(字符串s){
返回前缀+s;
}
});
打印字符串(“测试”,s->前缀+s);
}
私有静态void打印字符串(字符串基串、函数stringMapper){
System.out.println(stringMapper.apply(baseString));
}
}
这张照片

家长考试

局部检验


特别是,AIC中的
prefix
表示父类中的字段,而lambda中的
prefix
表示局部变量。

看到了这一点,您想不出一种情况,代码可能会根据
指向的对象而有不同的行为(或编译)?这应该不会太难。特别是关于
这个
:我的问题可以理解为“AIC和Lambda之间的范围差异是否使得
这个
在两者之间不同?如果是,在Lambda的情况下它指向什么?”是的,存在差异。在匿名类中,它指向匿名类实例。在lambda中,它指向lambda之外的任何东西。请注意,在未来的版本中,有一个正在考虑的问题可能会取消lambda中变量阴影的限制。看到了这一点,您想不出一个场景,其中代码的行为(或编译)可能会因
指向的内容而有所不同?这应该不会太难。特别是关于
这个
:我的问题可以理解为“AIC和Lambda之间的范围差异是否使得
这个
在两者之间不同?如果是,在Lambda的情况下它指向什么?”是的,存在差异。在匿名类中,它指向匿名类实例。在lambda中,它指向lambda之外的任何方法。请注意,在未来的版本中,有一个正在考虑的方法可能会取消lambda中变量阴影的限制。lambda不是(一定)静态方法。链接问题中的lambda只是在静态上下文中定义的。lambda不一定是静态方法。链接问题中的lambda只是在静态上下文中定义的。