问题“ 为什么`array [i ++%n] + = i +”在Java 8和Java 10中给出不同的结果? ”已于本周初发布在StackOverflow.com上 。 它指向JDK9和更高版本中存在的Java编译器中的错误 ,但JDK8中不存在。
如StackOverflow线程上所述, Didier L提供了一个简单的Java代码示例来重现此问题。 这将在下面显示的代码清单中进行调整。
package dustin.examples.strings;
import static java.lang.System.out;
/**
* Example demonstrating JDK-8204322 and adapted from Didier L's
* original example (https://stackoverflow.com/q/50683786).
*/
public class StringConcatenationBug
{
static void didierLDemonstration()
{
final String[] array = {""};
array[generateArrayIndex()] += "a";
}
static int generateArrayIndex()
{
out.println("Array Index Evaluated");
return 0;
}
public static void main(final String[] arguments)
{
didierLDemonstration();
}
}
阅读上面显示的代码,如果执行了此类的main(String[])
函数,则可以看到一次显示了字符串“ Array Index Evaluated”。 对于JDK8,情况就是这样,但是自JDK 9起,情况并非如此。 下一个屏幕快照对此进行了演示。 屏幕快照中显示的示例显示,当使用javac的-source
和-target
标志设置为“ 8 ”编译该类时,在执行该编译的类时,该字符串仅显示一次。 但是,当javac
的-source
和-target
标志设置为“ 9 ”时,在执行编译的类时,该字符串显示两次。
此错误存在于JDK9,JDK10和JDK11中。 OlivierGrégoire描述了此错误,“问题似乎仅限于字符串连接和赋值运算符( +=
),且表达式的副作用为左操作数。”
JDK-8204322 [针对字符串操作数应用“ + =”可能会引起副作用”已针对此错误编写,已解决,其解决方案当前针对JDK11 。 错误报告描述了问题,“当使用+ =运算符时,javac似乎在+ =之前复制了代码。” 它还说明了类似array[i++%n] += i + " ";
编写的代码array[i++%n] += i + " ";
有效地编译为类似于array[i++%n] = array[i++%n] + i + " ";
。 扬·拉霍达(Jan Lahoda) 对错误的评论描述了它发生的原因。 Aleksey Shipilev已要求将此修复程序反向移植到JDK 10,看来它将通过JDK-8204340进行 。
有关此错误的其他背景信息,可以在前面提到的StackOverflow线程 , 相关的StackOverflow聊天以及OpenJDK 编译器-dev邮件列表线程中找到“ 有关字符串连接的编译器错误 ”和“已应用RFR:8204322:'+ ='字符串操作数会引起 “ 副作用 ”。
翻译自: https://www.javacodegeeks.com/2018/06/jdk9-side-effects-java-string.html