我不明白 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 删除,因为没有指向该对象的指针。
还有一点,为什么我这里不需要返回语句?
Function<Integer, String> f = t -> t + "";
最佳答案
JLS, Section 15.13.3描述了方法引用的运行时评估。
The timing of method reference expression evaluation is more complex than that of lambda expressions (§15.27.4). When a method reference expression has an expression (rather than a type) preceding the :: separator, that subexpression is evaluated immediately. The result of evaluation is stored until the method of the corresponding functional interface type is invoked; at that point, the result is used as the target reference for the invocation. This means the expression preceding the :: separator is evaluated only when the program encounters the method reference expression, and is not re-evaluated on subsequent invocations on the functional interface type.
(大胆强调我的)
基本上,对s
的引用就像方法引用一样被存储起来供以后执行。此处,字符串 "Hello World"
被保存以供稍后执行方法引用。因此,即使在方法引用声明之后将 s
设置为 null
,但在执行 Function
之前,它仍然会使用字符串 "Hello World"
。
将某些内容设置为 null
并不能保证垃圾收集器会收集它,也不能保证它会立即被收集。
还有,在这里,方法引用中仍然有一个引用,所以这里根本不会被垃圾回收。
最后,lambda 表达式主体有 2 种形式:一个表达式和一个带有(可能)return 语句的语句 block 。与
Function<Integer, String> f = t -> t + "";
这是一个表达式。等效的 block 语句是:
Function<Integer, String> f = t -> { return t + "";};
关于java - Java 中指向 String 方法的函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51622262/