Che*_*oss 3 java lambda anonymous-class functional-interface
当使用下面的匿名类时,我们调用的变量x没有问题
interface Age {
int x = 21;
void getAge();
}
class AnonymousDemo {
public static void main(String[] args) {
Age oj1 = new Age() {
@Override
public void getAge() {
// printing age
System.out.print("Age is "+x);
}
};
oj1.getAge();
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我使用下面的 lambda 表达式相同的代码时,出现了异常:
interface Age {
int x = 21;
void getAge();
}
class AnonymousDemo {
public static void main(String[] args) {
Age oj1 = () -> { System.out.print("Age is "+x); };
oj1.getAge();
}
}
Run Code Online (Sandbox Code Playgroud)
这里会出现什么问题呢?知道lambda表达式只是实现匿名类的缩写。
小智 5
实际上 lambda 表达式并不是“只是实现匿名类的缩写”。使用 lambda 表达式的好处是它可以直接访问this类的实例(调用它的类),而匿名类则不能(它有自己的this实例)。
换句话说,匿名类引入了一个新的范围。以便名称从其超类和接口解析,并且可以隐藏词法封闭环境中出现的名称。对于 lambda,所有名称均按词法解析。
匿名类的 Lambda 性能
当应用程序启动时,必须加载并验证每个类文件。
编译器将匿名类处理为给定类或接口的新子类型,因此将为每个匿名类生成一个新的类文件。
Lambdas 在字节码生成方面有所不同,它们更高效,使用 JDK7 自带的 invokedynamic 指令。
对于 Lambda,此指令用于延迟翻译字节码中的 lambda 表达式,直到运行时。(仅第一次调用指令)
结果,Lambda 表达式将成为静态方法(在运行时创建)。(有状态和有状态的情况有细微差别,它们通过生成的方法参数解决)
例如:
interface Supplier {
void foo();
}
class A {
private String name;
public void doSome() {
baz(() -> System.out.println(this.name));
}
private void baz(Supplier sup){
sup.foo();
}
}
Run Code Online (Sandbox Code Playgroud)
或者
class A {
private String name;
public void doSome() {
baz(new Supplier() {
void foo() {
System.out.println(A.this.name);
}
});
}
private void baz(Supplier sup){
sup.foo();
}
}
Run Code Online (Sandbox Code Playgroud)
我建议阅读以下内容:Java8 Lambdas vs Anonymous classes。
| 归档时间: |
|
| 查看次数: |
4991 次 |
| 最近记录: |