问题描述
我不明白 lambda 的一些事情.
I don't understand a couple of things with lambda.
String s = "Hello World";
Function<Integer, String> f = s::substring;
s = null;
System.out.println(f.apply(5));
如果 s = null
,为什么 f.apply
方法仍然有效.毕竟String
对象应该被GC删除,因为没有指向该对象的指针.
Why is the f.apply
method still working if s = null
. After all, the String
object should be deleted by the GC because there is no pointer that points to the object.
还有一件事,为什么我在这里不需要 return 语句?
One more thing, why don't I need a return statement here?
Function<Integer, String> f = t -> t + "";
推荐答案
JLS,第 15.13.3 节 描述了方法引用的运行时评估.
The JLS, Section 15.13.3 describes the runtime evaluation of method references.
方法引用表达式求值的时间比 lambda 表达式(第 15.27.4 节)更复杂.当方法引用表达式在 :: 分隔符之前有一个表达式(而不是一个类型)时,该子表达式会被立即计算.求值的结果一直保存到对应的函数接口类型的方法被调用;此时,结果将用作调用的目标引用.这意味着 :: 分隔符之前的表达式仅在程序遇到方法引用表达式时才计算,并且不会在功能接口类型的后续调用中重新计算.
(粗体强调我的)
基本上对 s
的引用作为方法引用被存储以供以后执行.在这里,字符串 "Hello World"
被保存以供以后执行方法引用.因此,即使在方法引用声明之后将s
设置为null
,但在执行Function
之前,它仍然会使用字符串 "Hello World"
.
Basically the reference to s
as it is for the method reference is stored for later execution. Here, the string "Hello World"
is saved for later execution of the method reference. Because of this, even if you set s
to null
after the declaration of the method reference, but before you execute the Function
, it will still use the string "Hello World"
.
将某些内容设置为 null
并不能保证垃圾收集器会收集它,也不能保证它会立即被收集.
Setting something to null
does not guarantee that the garbage collector will collect it, and it won't guarantee that it's collected immediately.
另外,这里的方法引用中还有一个引用,所以这里根本不会被垃圾回收.
Also, here, there still is a reference in the method reference, so it won't get garbage collected at all here.
最后,lambda 表达式主体有两种形式:一个表达式和一个带有(可能)一个 return 语句的语句块.随着
Finally, lambda expression bodies have 2 forms: an expression and a block of statements with (possibly) a return statement. With
Function<Integer, String> f = t -> t + "";
这是一个表达.等效的块语句是:
That is an expression. The block statement equivalent would be:
Function<Integer, String> f = t -> { return t + "";};
这篇关于Java中指向String方法的函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!