JDKのバグっぽい動きの続き

id:masataka_kさんに言われて-serverつけて動かしてみたら、ちゃんと動きました。あと、continueの代わりにラベル付きbreak使ってみたら再現しました。
現象から考えると、continueを抜けたときに値が変わるんじゃなくて、preの値が本当は変わっていないんじゃないかと思います。
HotSpotの気持ちで考えると、preの値を書き換えたときにすぐcontinueしているので、その値はそのブロックでしか使わないと判断してブロックローカルとして最適化しちゃってるんじゃないかと思います。で、そのブロックでの変更がブロックの外側に反映されないって感じかと。


みずしまさんが書かれてた通り、スタンドアローンでも再現します。っていうか、自分で試してなかなか再現しないと思ってたらJDK5で動かしてました。

public class Problem {
    static public void process(){
        boolean brk = true;//順番を逆にすると再現しない intでも再現
        boolean pre = false;
        System.out.println("---start---");
        for(int i = 0; i < 2; ++i){
            for(int j = 0; j++ < 1; ){
                System.out.println("top:" + pre);
                if(i < 1){
                    if(i == 0){
                        pre = brk;
                        brk = false;
                        System.out.println("con:" + pre);
                        continue;
                    }
                }
            }
        }
        for(int i = 0; i < 10000; ++i);//数値を短くすると最適化までの時間が延びる?
        
    }
    
    public static void main(String args[]){
        for(int i = 0; i < 3; ++i){
            process();
        }        
    }
}


実行すると次のようになります。3回目の結果が変わってますが、ほんとうは同じ結果になるはずです。

 ---start---
top:false
con:true
top:true
 ---start---
top:false
con:true
top:true
 ---start---
top:false
con:true
top:false