您现在的位置是:首页 > 文章详情

jdk9+版本的bug

日期:2018-06-05点击:425

今天从jvm大神"你假笨"的公众号上,看到一个jdk 9+版本的编译bug,记录一下:

public class JavacEvalBug{ private static String[] array = {""}; static int test(){ System.out.println("evaluated!"); return 0; } public static void main(String[] args) { //相当于int index=test(); array[index] +="a"; array[test()] += "a"; } } 

test()方法里输出了一个固定字符串,上面这段代码,如果是在jdk8版本里,执行后,只会输出:evaluated! 一次(这符合预期,因为test()只调用了1次)

但如果把jdk升级到jdk9或10,再次编译运行,evaluated!就会输出2次,即test()方法会多执行了1次,如果test()方法是复杂的业务逻辑,比如创建订单/库存扣减之类,这就成大问题了。

原因在于jdk8与jdk9+的编译机制不同,javap -verbose JavacEvalBug  使用这个命令,可以看到编译细节:

 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=5, locals=1, args_size=1 0: new #5 // class java/lang/StringBuilder 3: dup 4: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V 7: getstatic #7 // Field array:[Ljava/lang/String; 10: invokestatic #8 // Method test:()I 13: dup2_x1 14: aaload 15: invokevirtual #9 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 18: iconst_1 19: invokevirtual #10 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 22: invokevirtual #11 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 25: aastore 26: return 

jdk8上,从第10行看,只调用了1次,如果切换到jdk9+,则会变成:

 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: stack=4, locals=1, args_size=1 0: getstatic #5 // Field array:[Ljava/lang/String; 3: invokestatic #6 // Method test:()I 6: getstatic #5 // Field array:[Ljava/lang/String; 9: invokestatic #6 // Method test:()I 12: aaload 13: invokedynamic #7, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String; 18: aastore 19: return LineNumberTable: 

明显可以看到Method test:()I 调用了2次。具体详情分析,大神说是以后会详细分析,大概是字符串拼写的方式,jdk9以后做了变化。如果把string数组换成其它类型比如int

public class JavacEvalBug{ private static int[] array = {0}; static int test(){ System.out.println("evaluated!"); return 0; } public static void main(String[] args) { //相当于int index=test(); array[index] +=1; array[test()] += 1; } } 

就正常了

 

2018-07-28 更新,在jdk 10.0.2版本上,该bug已修复

作者: 菩提树下的杨过
出处: http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文链接:https://yq.aliyun.com/articles/620195
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章