当Java8使用引用透明性时
我们注意到java 8使用: 我测试了许多代码来检测此RT,例如:当Java8使用引用透明性时,java,java-8,referential-transparency,Java,Java 8,Referential Transparency,我们注意到java 8使用: 我测试了许多代码来检测此RT,例如: public class ReferentialTransparency { public static int triple(int number) { System.out.println(number); try { Thread.sleep(500); } catch (Exception e) {
public class ReferentialTransparency {
public static int triple(int number) {
System.out.println(number);
try {
Thread.sleep(500);
} catch (Exception e) {
}
return number* 3;
}
public static void main(String[] args) {
List<Integer> vals=Arrays.asList(1,2,3,4,3);
System.out.println(vals.parallelStream()
.mapToInt(ReferentialTransparency::triple)
.sum());
}
}
我注意到Java8运行三重方法,即使有一个元素出现了两次,即3
我的问题,正如伊斯特万所解释的,是:
为什么编译器不优化对triple(3)的重复调用
如果triple是引用透明的
您的
triple
方法在引用上是不透明的,因为它会将内容打印到控制台并休眠。这两个动作都不是透明的。事实上,很难(从代码中)检测编译器是否优化了对引用透明函数的任何调用,因为如果添加一个print语句来检测它,那么根据定义,函数不再是引用透明的
请注意,在您提供给的链接中,给出了引用透明度的定义 函数的一种属性,通过该属性,表达式可以被其(已计算的)值替换,而不影响程序的含义
您可以看出,
triple
在引用上是不透明的,因为调用例如triple(2)
并不等同于6
,因为仅计算6
不会打印任何内容或睡眠,而triple(2)
也会将2打印到控制台并睡眠一秒钟。由于将triple(2)
替换为6
会通过删除打印和休眠来影响程序的意义,triple
在引用上是不透明的。您的问题是什么?我相信这可以在不使用引用透明度的情况下解决/回答,这会使你的问题无效。虽然我没有看到问题,但问题的示例和答案的解释都是信息性的。我将问题解释为“为什么编译器不优化对triple(3)的重复调用?”
iftriple
是否具有引用透明性?“感谢您的详细解释。我真希望Java有用于引用透明方法的注释,IDE会为这类事情提供编译器警告。
3
4
2
1
3
39