(参与人员:Boyarsky和Selikoff的OCP Java 17认证指南中的示例)
为了更好地学习lambdas,我在代码(IntelliJ IDE)中放置了一个断点,并开始逐步执行。
Function<Integer, Integer> before = x -> x + 1;
Function<Integer, Integer> after = x -> x * 2;
Function<Integer, Integer> combinedf = after.compose(before);
System.out.println(combinedf.apply(3));
我很惊讶地发现x
的值已经被赋值了。
当我跳到下一行时,在调用combinedf.apply()
之前再次计算它
我不明白为什么。
我想这可能是由于编译器优化,并试图通过不硬编码'3'来欺骗它。
Scanner scanner = new Scanner(System.in);
Function<Integer, Integer> before = x -> x + 1;
Function<Integer, Integer> after = x -> x * 2;
Function<Integer, Integer> combinedf = after.compose(before);
System.out.println(combinedf.apply(scanner.nextInt()));
但我得到了同样的结果。
我按照@wuhoyt的建议,将断点设置为All。我还拆分了代码。现在它按预期显示。我不明白为什么断点必须设置为All才能按预期工作。
Scanner scanner = new Scanner(System.in);
Function<Integer, Integer> before = x -> x + 1;
Function<Integer, Integer> after = x -> x * 2;
Function<Integer, Integer> combinedf = after.compose(before);
Integer intput = scanner.nextInt();
Integer result = combinedf.apply(intput);
System.out.println(result);
1条答案
按热度按时间kuarbcqp1#
您可以在创建函数对象的代码上设置2个断点。
当我试图在这一行中放置断点时,它告诉我要放置断点位置,并给予了3个选项
1.线条
1.全部
我选择了“All”,然后在第一行中放置了另一个断点
调试过程从
换句话说
我正在使用IDEA 2021社区,当我点击行的左侧区域放置断点时,它给予了我3个选项
更新
为什么必须为断点选择“全部”?
我猜你是在问为什么会有两个地方,有什么不同?
可能是因为函数式编程中的惰性初始化概念。一开始,函数体不会被执行,当你最后调用apply方法(terminal operation)时,函数体会被执行。这样你就可以链接这些函数,或者用lambda表达式做其他很酷的事情。至少有两个步骤,所以你有两个地方可以设置断点。
我在这里找到了另一个答案,非常好,一定要去看看
https://stackoverflow.com/a/24542150/16702058