2

我们注意到 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());
        }
}

安慰 :

3
4
2
1
3
39

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

正如 Istvan 解释的那样,我的问题 是:

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

4

1 回答 1

8

您的triple方法不是引用透明的,因为它既会在控制台上打印一些东西又会进入睡眠状态。这些动作都不是参照透明的。实际上,很难(从您的代码中)检测编译器是否优化了对引用透明函数的任何调用,因为如果您添加一个 print 语句来检测它,那么根据定义,您的函数就不再是引用透明的。


请注意,在您提供给的链接中,给出的引用透明度的定义是

函数的一种属性,可以用它的(计算的)值替换表达式而不影响程序的含义。

您可以看出它triple不是引用透明的,因为对 eg 的调用triple(2)不等同于6,因为仅评估6不会打印任何内容或休眠,同时triple(2)还会将 2 打印到控制台并休眠一秒钟。由于替换triple(2)by6会通过删除打印和睡眠来影响程序的含义,triple因此不是引用透明的。

于 2014-05-23T12:31:39.230 回答