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

2回出現する要素があっても、Java 8はトリプルメソッドを実行することに注意してください3.

Istvan の解釈によると、私の質問は次のとおりです。

トリプルが参照透過的である場合、コンパイラはトリプル(3)への繰り返し呼び出しを最適化しないのはなぜですか?

4

1 に答える 1

8

tripleメソッドは、コンソールに何かを出力してスリープするため、参照透過的ではありません。これらのアクションはどちらも参照透過的ではありません。実際、コンパイラが参照透過関数の呼び出しを最適化するかどうかを (コード内から) 検出することは非常に困難です。それを検出するために print ステートメントを追加すると、定義により、関数は参照透過ではなくなるからです。


に指定したリンクでは、指定された参照透過性の定義は次のとおりであることに注意してください

プログラムの意味に影響を与えることなく、式をその (評価された) 値で置き換えることができる関数のプロパティ。

eg への呼び出しは と同等ではないtripleため、 は参照透過的ではないことがわかります。評価するだけでは何も出力されず、スリープも行われず、コンソールに 2 が出力され、1 秒間スリープするからです。で置き換えると、印刷とスリープが削除されてプログラムの意味に影響を与えるため、参照透過ではありません。triple(2)66triple(2)triple(2)6triple

于 2014-05-23T12:31:39.230 に答える