String类对象相加时做了什么
我们都知道java中的加号操作符除了加法、表示正数之外,还可以用作字符串的连接。初学java时,你很可能会碰到类似下面的题目:
以下这段代码产生了几个String对象:
String str1 = "abc" + "def";
String str2 = "123" + new String("456");
我还记得以前看过的文章是这样分析的:第一行先产生abc和def,再产生一个新的abcdef,共3个;第二行先产生123,再产生一个456,最后再产生一个123456,共3个;一共产生了6个String对象。
先说结论,上面的分析过程是错误的,这两段代码一共产生了5个String对象。下面是验证过程:
先编译,然后再反编译可以得到下面的代码:
String var1 = "abcdef";
String var2 = "123" + new String("456");
可以看到第一行在编译的阶段就直接把两个字符串常量的连接结果计算出来了,直接在常量池生成一个abcdef字符串,所以只产生了一个String对象;而第二行并没有进行计算,即使我们可以很直观地看出计算结果。在有new的地方,只有在运行阶段才会去动态分配内存,然后进行初始化的,所以第二行会生成4个String对象,即在常量池生成一个123和一个456对象,再在堆中生成456和123456两个String对象。
然后回到字符串相加的问题,上面两行代码都是字符串相加,分别做了什么呢?可以用javap -c反汇编查看指令如下:
0: ldc #2 // String abcdef
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: ldc #5 // String 123
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: new #7 // class java/lang/String
18: dup
19: ldc #8 // String 456
21: invokespecial #9 // Method java/lang/String."<init>":(Ljava/lang/String;)V
24: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
27: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
30: astore_2
31: return
可以看到第一行是在编译阶段就把两个常量字符串相加好了直接生成了字符串常量;第二行代码做的工作比较多,先是生成了一个StringBuilder对象,然后append了123,接着生成一个String对象,值为456,接着再被append到StringBuilder中,最后再调用toString方法得到了最终的字符串。
再看一个例子,下面的代码做了怎样的操作?
String str1 = 1 + 2 + "345";
String str2 = 1 + 2 + new String("345");
用同样的方法,用javap命令对class文件反汇编查看指令:
0: ldc #2 // String 3345
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: iconst_3
11: invokevirtual #5 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
14: new #6 // class java/lang/String
17: dup
18: ldc #7 // String 345
20: invokespecial #8 // Method java/lang/String."<init>":(Ljava/lang/String;)V
23: invokevirtual #9 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
26: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
29: astore_2
30: return
第一行依然是在编译阶段就完成了计算;第二行还是使用了StringBuilder对象,先在编译阶段计算了1+2的值,然后再用append方法拼接后toString获得结果。
String类对象相加时做了什么的更多相关文章
- 反射消除String类对象的不可变特性
大家都知道,在JAVA中字符串一旦声明就不可改变,如果尝试修改字符串的内容,将会重新实例化一个新的字符串对象,这也是为了安全性和效率. 由于字符串在程序之中被大量使用,所以JAVA引入了一个字符串常量 ...
- java笔记--String类对象解析与运用
--如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3877236.html "谢谢-- 1.String中的equals和==的 ...
- String类对象两种实例化方式比较
第一种:直接赋值 String str = "hello!" ; 在java中,有一个字符串常量池,对于这种直接赋值的,会直接写进常量池(常量池里面不存在其value,) 自JD ...
- JAVA笔记3__字符串String类/对象一对一关联
import java.lang.String; import java.util.Scanner; public class Main { public static void main(Strin ...
- c++中string类对象和字符数组之间的相互转换
string类在c++中是一个模板类,位于名字空间std中,注意这里不是string.h,string.h是C字符串头文件. 将string类型转换为字符数组char arr[10];string s ...
- String类的写时拷贝
#include<iostream>using namespace std; class String;ostream& operator<<(ostream & ...
- String类对象的比较
1.字符串比较,是按照字符串(String)中每一个字符(char)的字段表顺序进行比较 /** * Compares two strings lexicographically(字典序,按照字典顺序 ...
- Scanner类、匿名对象、Random类、ArrayList集合、String类、static静态类、math类和Arrays工具类
一.Scanner类 1.除了八种基本数据类型,其他都是引用类型: 引用类型使用三步骤: 2.Scanner类 引用jdk提供的类,Scanner在java.util包下,不在java.lang包(S ...
- 跟着刚哥梳理java知识点——深入理解String类(九)
一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class String implements java.io.Ser ...
随机推荐
- Linux-鸟菜-1-Linux简介
Linux-鸟菜-1-Linux简介 鸟哥这一章是介绍了Linux的由来以及建议怎么学Linux.很多也是建议性的东西,概念性的东西(当然我不是排斥概念).把最后鸟哥的汇总粘过来吧. 建议大家去看下这 ...
- android 资料
https://xfans.gitbooks.io/android-book/content/issue-39/Android%20dex%E5%88%86%E5%8C%85%E5%AF%BC%E8% ...
- 简单写个logictic回归
最近做华为软件精英挑战赛热身赛,给出的demo是使用logistic做的金融风控,比赛要求很严格,如果使用Python 进行训练那么不能使用任何第三方机器学习库,只能使用Python和原生numpy1 ...
- 【微信小程序】--bindtap参数传递,配合wx.previewImage实现多张缩略图预览
本文为原创随笔,纯属个人理解.如有错误,欢迎指出. 如需转载请注明出处 在微信小程序中预览图片分为 a.预览本地相册中的图片. b.预览某个wxml中的多张图片. 分析:实质其实是一样的.都是给wx. ...
- 多变量高斯(MVN)概率建模的两种方案
摘要:在我们的时序异常检测应用中,设计了对时序数据进行多变量高斯(MVN)建模的算法方案进行异常检测,本文对基于tensorflow的两种MVN建模方案进行了总结. 1.基于custom choles ...
- 浅谈自动特征构造工具Featuretools
简介 特征工程在机器学习中具有重要意义,但是通过手动创造特征是一个缓慢且艰巨的过程.Python的特征工程库featuretools可以帮助我们简化这一过程.Featuretools是执行自动化特征工 ...
- 发布 .NET 5 带运行时单文件应用时优化文件体积的方法
自 .NET 发布起,.NET Framework 运行环境就是其摆脱不掉的桎梏.后来有了 .NET Core ,微软终于将自带运行时和单文件程序带给了我们.即便如此,大部分情况下开发者仍然不太满意: ...
- [bug] @Test注解无法使用
参考 https://blog.csdn.net/lixiangxiang666/article/details/83745901
- [刷题] 435 Non-overlapping Intervals
要求 贪心算法与动态规划的关系 给定一组区间,最少删除多少个区间,可以让这些区间之间互相不重叠 给定区间的起始点永远小于终止点 示例 [[1,2],[2,3],[3,4],[1,3]], 返回1 [[ ...
- python上下文管理协议,即with的详细使用
一.with obj as f: #代码块... 二.执行流程: 1.with obj --->触发obj.__enter__(),需要在obj里写__enter__(self),在它里边写返回 ...