两道小题目

本贴最后更新于 3074 天前,其中的信息可能已经时异事殊

两道小题目

@Test public void test7() { String s1 = "abc"; String s2 = "ab"; String s3 = "c"; String s4 = s2 + s3; String st0 = "helloworld"; String st1 = "helloworld"; String st2 = "hello" + "word"; System.out.println(st0 == st2); System.out.println(s1 == (s2 + s3)); System.out.println(s1 == s4); }
@Test public void test8() { int i = 0; i = i++; System.out.println(i); }
  • 第一题结果均为 false
  • 第二题结果为 0

解析

利用 javap 反汇编查看 jvm 执行指令

第一题

public void test7(); Code: 0: ldc #39 // String abc 2: astore_1 3: ldc #40 // String ab 5: astore_2 6: ldc #41 // String c 8: astore_3 9: new #19 // class java/lang/StringBuilder 12: dup 13: invokespecial #20 // Method java/lang/StringBuilder."<init>":()V 16: aload_2 17: invokevirtual #22 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 20: aload_3 21: invokevirtual #22 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 24: invokevirtual #25 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 27: astore 4 29: ldc #42 // String helloworld 31: astore 5 33: ldc #42 // String helloworld 35: astore 6 37: ldc #43 // String helloword 39: astore 7 41: getstatic #18 // Field java/lang/System.out:Ljava/io/PrintStream; 44: aload 5 46: aload 7 48: if_acmpne 55 51: iconst_1 52: goto 56 55: iconst_0 56: invokevirtual #33 // Method java/io/PrintStream.println:(Z)V 59: getstatic #18 // Field java/lang/System.out:Ljava/io/PrintStream; 62: aload_1 63: new #19 // class java/lang/StringBuilder 66: dup 67: invokespecial #20 // Method java/lang/StringBuilder."<init>":()V 70: aload_2 71: invokevirtual #22 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 74: aload_3 75: invokevirtual #22 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 78: invokevirtual #25 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 81: if_acmpne 88 84: iconst_1 85: goto 89 88: iconst_0 89: invokevirtual #33 // Method java/io/PrintStream.println:(Z)V 92: getstatic #18 // Field java/lang/System.out:Ljava/io/PrintStream; 95: aload_1 96: aload 4 98: if_acmpne 105 101: iconst_1 102: goto 106 105: iconst_0 106: invokevirtual #33 // Method java/io/PrintStream.println:(Z)V 109: return

可以看出字符串变量相加实际上 JVM 是优化为 java/lang/StringBuilder.append, 最终输出为 java/lang/StringBuilder.toString。

new String 则是直接引用堆中的对象,而 “” 则是引用常量池中的字符串, 这就是三个输出均为 false 的原因。

第二题

public void test8(); Code: 0: iconst_0 -- 将常量0加载进栈中, 入栈 1: istore_1 -- 将栈顶int赋值给变量1,出栈 2: iload_1 -- int变量1入栈 3: iinc 1, 1 -- 变量1自增1,不会入栈 i = 1 6: istore_1 -- 将栈顶int赋值给变量1,出栈 i = 0 7: getstatic #18 // Field java/lang/System.out:Ljava/io/PrintStream; 10: iload_1 -- int变量1入栈 11: invokevirtual #29 // Method java/io/PrintStream.println:(I)V 14: return

由于执行完 iinc 1, 1 指令之后并没有将变量 i 入栈,然后直接将栈顶的 0 赋值给了变量 i

而栈顶的 0 来自于 i++ 的 0。这就导致了最终的输出结果0

对比

@Test public void test8() { int i = 0; i++; System.out.println(i); }
public void test8(); Code: 0: iconst_0 1: istore_1 2: iinc 1, 1 5: getstatic #18 // Field java/lang/System.out:Ljava/io/PrintStream; 8: iload_1 9: invokevirtual #29 // Method java/io/PrintStream.println:(I)V 12: return
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3194 引用 • 8214 回帖

相关帖子

9 回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • yanny

    String st1 = "helloworld";
    String st2 = "hello" + "word";
    word 改成 world 是相等的

    1 回复
  • 其他回帖
  • yangyujiao via macOS

    1477635091992

    这是怎么看的,,,怎么出现的这些过程。。。

    1 回复
  • eddy
    作者

    是的,就是考你细心不,哈哈。

  • MrWang

    第一题第一个就是 true,是你把 world 写错成 word。它怎么也不会变成 true。

  • 查看全部回帖