如果将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只是在静态上下文中定义的。