当Java8使用引用透明性时



我们注意到java 8使用了引用透明度:

我测试了许多代码来检测这个RT,例如:
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());
        }
}
CONSOLE:
3
4
2
1
3
39

我注意到Java 8运行三重方法,即使有一个元素出现了两次,即3

我的问题,按照Istvan的解释,是:

为什么编译器不优化掉对triple(3)的重复调用?如果triple是引用透明的?

您的triple方法不是引用透明的,因为它既向控制台打印内容,又休眠。这两种操作都不是引用透明的。事实上,(从代码中)检测编译器是否优化了对引用透明函数的任何调用是相当困难的,因为如果您添加了print语句来检测它,那么根据定义,您的函数不再是引用透明的。


请注意,在您提供给reference -transparency的链接中,给出的reference -transparency的定义是

函数的一种属性,在不影响程序意义的情况下,表达式可以被其(求值)替换。

你可以告诉triple不是引用透明的,因为对triple(2)的调用不等同于6,因为仅仅评估6不会打印任何东西或睡眠,而triple(2)也会将2打印到控制台并睡眠一秒钟。由于用6替换triple(2)会影响程序的意义,因为它删除了打印和休眠,所以triple不是引用透明的。

相关内容

  • 没有找到相关文章

最新更新