2

如果您搜索“java 双括号”,您会发现反对使用它的有力论据。

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

论点是您创建了太多匿名类,并且您可能会造成内存泄漏。

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

4

2 回答 2

2

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

匿名内部类将在编译时创建自己的类文件Foo$1.class,如果它包含在Foo类中,通常类似于 。它是实现接口或子类的全功能类。要在其范围之外引用本地值,它将在幕后在匿名内部类中创建一个实例变量,以表示该值的副本。这就是为什么变量必须是有效的最终变量——否则实际变量可能会改变并且副本可能是陈旧的。

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

资料来源:

于 2019-04-24T20:21:21.323 回答
1

是的,它们是不同的。

  • Lambda 实际上并不一定要创建匿名类——它们当然不只是被翻译成等效的匿名类。它们的创建比这要复杂得多,并且通常以在运行时创建的匿名类结束,但不一定。
  • Lambdas 除了特别提到的变量外不捕获任何东西,这与匿名内部类不同,如果它们是在实例方法中定义的,它会捕获封闭的类对象。
于 2019-04-24T20:05:57.870 回答