Java双括号初始化与Lambda

时间:2019-04-24 19:55:40

标签: java lambda double-brace-initialize

如果搜索“ java双括号”,则会发现反对使用它的强烈理由。

  

每当有人使用双括号初始化,一只小猫就会被杀死。   https://stackoverflow.com/a/27521360/555631

参数是您正在创建太多的匿名类,并且可能会导致内存泄漏。

lambdas有什么不同吗?他们每个人都创建一个匿名内部类,他们每个人都引用其封闭的闭包。

2 个答案:

答案 0 :(得分:2)

Lambda表达式不同于碰巧实现功能接口的匿名内部类。

匿名内部类将在编译时创建自己的类文件,如果它们包含在Foo$1.class类中,则通常类似于Foo。它是一个功能齐全的类,可实现接口或为类提供子类。要引用超出其范围的局部值,它将在后台在匿名内部类中创建一个实例变量,该实例变量表示该值的 copy 。这就是为什么变量必须有效地为final的原因-否则实际变量可能会更改,并且副本可能已过时。

Lambda表达式不会创建匿名内部类。它们使用产生java.lang.invoke.LambdaMetafactory的{​​{1}},以后可以使用它们执行lambda表达式。 Lambda表达式(无论是块还是表达式)都将转换为包含它的类中的隐藏的私有静态方法。不是使用隐藏变量创建类,而是将捕获的值转换为隐藏的私有静态方法的参数。局部值仍然必须是有效的最终值,因为传递给该方法的值还是一个副本。该方法由JVM中的CallSite指令调用。

来源:

答案 1 :(得分:1)

是的,它们是不同的。

  • Lambda实际上不一定创建匿名类-当然,它们不只是被翻译成等效的匿名类。他们的创建比这复杂得多,并且通常以在运行时创建一个匿名类而告终,但不一定。
  • 与匿名内部类不同,Lambda除了它们中特别提到的变量外,不捕获其他任何东西,而匿名内部类则可以捕获封闭的类对象(如果它们是在实例方法中定义的)。