Java9、10でStringの+=に副作用があるバグ

Java 9、10でStringの+=にバグがあるということがStack OverFlowで報告されていました。
Why does array[idx++]+="a" increase idx once in Java 8 but twice in Java 9 and 10? - Stack Overflow


どういうバグかというと「s[i++] += i + ""」のようなコードが正しく動かないというものです。
次のコードを実行してみます。

public class PlusEqual {
    public static void main(String[] args) {
        System.out.print(System.getProperty("java.version"));

        String[] s = {"aa", "bb"};
        int i = 0;
        s[i++] += i + "";
        System.out.printf(" %s %d%n", Arrays.toString(s), i);
    }
}


Java 8では期待通りに動きます。

1.8.0_151 [aa1, bb] 1


ところが、JDK10.0.1では次のようになります。

10.0.1 [bb2, bb] 2


おもしろいのは、target=8とするとJDK10でもJava8と同じように動くところです。

10.0.1 [aa1, bb] 1


これは、「s[i++] += i + ""」が「s[i++] = s[i++] + i + ""」のように扱われていると考えることができます。
JDK11ea17で修正されています。JDK10.0.2はどうなるのかな。バックポートはされる予定。Java9はメンテナンスリリースは公開されないので、そのまま。
JDK-8204322 "+=" applied to String operands can provoke side effects - Java Bug System


で、このバグレポートはJEP280に関連づけられてるので、+演算子をdynamicInvoke使う実装にしたときにエンバグしたっぽいですね。
JEP 280: Indify String Concatenation
Java8までのJVMでは もちろん文字列結合のdynamicInvokeに対応していないので、target=8としたときには問題が発生しない、と。
なので、Java9やJava10.0.1でtarget=8したくない場合は-XDstringConcat=inline をつけてコンパイルすれば問題を回避することができるようです。