String拼接符"+"在编译期做了什么?
来源:互联网 发布:mac os 10.13 开机慢 编辑:程序博客网 时间:2024/06/08 18:45
用一个我多次遇到的字符串题目来说明:
String a="hello"; String b="hell"; String c=b+"o"; String d="hell"+"o"; System.out.println(a==b+new String("o")); System.out.println(a==c); System.out.println(a==d);
输出结果为:
false
false
true
为什么是这个结果呢?我们看一下反编译后的代码分析下:
Code: 0: ldc #2 // String hello 2: astore_1 3: ldc #3 // String hell 5: astore_2 6: new #4 // class java/lang/StringBuilder 9: dup 10: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V 13: aload_2 14: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 17: ldc #7 // String o 19: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 25: astore_3 26: ldc #2 // String hello 28: astore 4 30: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream; 33: aload_1 34: new #4 // class java/lang/StringBuilder 37: dup 38: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V 41: aload_2 42: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 45: new #10 // class java/lang/String 48: dup 49: ldc #7 // String o 51: invokespecial #11 // Method java/lang/String."<init>":(Ljava/lang/String;)V 54: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 57: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 60: if_acmpne 67 63: iconst_1 64: goto 68 67: iconst_0 68: invokevirtual #12 // Method java/io/PrintStream.println:(Z)V 71: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream; 74: aload_1 75: aload_3 76: if_acmpne 83 79: iconst_1 80: goto 84 83: iconst_0 84: invokevirtual #12 // Method java/io/PrintStream.println:(Z)V 87: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream; 90: aload_1 91: aload 4 93: if_acmpne 100 96: iconst_1 97: goto 101 100: iconst_0 101: invokevirtual #12 // Method java/io/PrintStream.println:(Z)V 104: return
通过反编译的代码我们可以发现
String d="hell"+"o"
在编译时就已经把d当成了hello
,指向的是字符串常量池中的对象,所以a==d为TRUE。
String c=b+"o"
和b+new String("o")
,只要字符串拼接中有对象时,就会创建StringBuilder对象,然后用append方法拼接,最后调用StringBuilder的toString方法返回一个重新创建的字符串。所以与a比较为FALSE。
说到这里,可能会有疑问,既然+
是用的StringBuilder
进行拼接,那为什么当大量用到字符串拼接时,我们会说用+
性能低,要用专门的StringBuilder
类?
有兴趣的朋友可以反编译下这两种拼接的代码进行对比。当大量拼接字符串时,+
会循环创建StringBuilder
类,所以不如只创建了一个的StringBuilder
性能高。也就是说编译器对+
的优化是有限的,大量拼接字符串还是使用StringBuilder
吧
最后补充一下字符串的创建过程:
- ” ” 引号创建的字符串在字符串池中
- new,new创建字符串时首先查看池中是否有相同值的字符串,如果有,则拷贝一份到堆中,然后返回堆中的地址;如果池中没有,则在堆中创建一份,然后返回堆中的地址(注意,此时不需要从堆中复制到池中,否则导致浪费池的空间)
0 0
- String拼接符"+"在编译期做了什么?
- 在JSP编译的时候,服务器内部做了什么?
- 在JSP编译的时候,服务器内部做了什么?
- 理解编译器在编译过程中做了什么
- 编译时,GCC做了什么?
- String s3 = "hel" + new String("lo");做了什么
- VC的IDE在编译链接时做了些什么
- 动态代理的疑问:在程序的编译阶段,new操作都做了什么
- 如何理解编译期和运行期的概念?它们分别干了什么
- VC的IDE在编译链接时做了些什么--- 逆向工程写自己的vcspawn
- VC的IDE在编译链接时做了些什么--- 逆向工程写自己的vcspawn
- c++ new 运算符做了什么
- new运算符做了什么
- 今天做了什么?
- 该做什么了?
- 今天做了什么?
- using做了什么?
- 今天做了什么
- Android Studio中如何使用SlidingMenu框架
- Strategy_Level1
- PAT 1039. Course List for Student (25)(倒搜索,注意scanf和string时间消耗大)
- 写了一个开机启动,监听通话的demo
- JMeter压测基础篇:linux服务器执行压测三部曲之二
- String拼接符"+"在编译期做了什么?
- Android ListView使用BaseAdapter与ListView的优化
- 【NOIP2016提高A组模拟9.7】总结
- 实现购物网站最近浏览商品的流程
- Office Skills
- 无法控制的并发问题
- HDU:2571 命运
- PyQT4文本框中文显示编码问题详解
- 基于GOLDENGATE实现数据实时分发