当我使用Java 8的新语法糖迭代一个集合时,例如
myStream.forEach(item -> {
// do something useful
});
Run Code Online (Sandbox Code Playgroud)
这不等同于下面的"旧语法"片段吗?
myStream.forEach(new Consumer<Item>() {
@Override
public void accept(Item item) {
// do something useful
}
});
Run Code Online (Sandbox Code Playgroud)
这是否意味着Consumer每次迭代集合时都会在堆上创建一个新的匿名对象?这需要多少堆空间?它有什么性能影响?这是否意味着我在迭代大型多级数据结构时应该使用旧样式for循环?
事实:
javac被编程以检测变量是否final或如果它可以被有效地 处理final.
证明:
此代码说明了这一点.
public static void finalCheck() {
String str1 = "hello";
Runnable r = () -> {
str1 = "hello";
};
}
Run Code Online (Sandbox Code Playgroud)
这无法编译,因为编译器能够检测到正在函数中重新分配String引用str1.
现在
情况1:
Javac final String通过避免创建StringBuilder和相关操作来对实例进行了很好的优化.
证明
这个java方法
public static void finalCheck() {
final String str1 = "hello";
final String str2 = "world";
String str3 = str1 + " " + str2;
System.out.println(str3);
}
Run Code Online (Sandbox Code Playgroud)
编译成
public static void finalCheck();
Code:
0: ldc …Run Code Online (Sandbox Code Playgroud) java final compiler-optimization language-lawyer javacompiler