String 简单分析
来源:互联网 发布:vscode debug webpack 编辑:程序博客网 时间:2024/06/05 04:36
- String 基本常识
- String 内存分配
- 直接赋值
- 通过new
- String 的比较主要是 equals
- String StringBuffer StringBuilder
String 基本常识
- 通过直观看代码得到的 String 是 final 的不可继承
- String 对象是不可变的。查看源码或者JDK文档可以看出来,String里面每一个会修改String值的方法,都会创建一个新的对象
- 基于 特征2 所以涉及到String的效率问题
String 内存分配
- 常量池
- 堆
这里面有个隐藏的问题,就是关于常量池的位置。
在JDK1.6以前(包括JDK1.6)常量池是在*方法区的
在JDK1.7的时候常量池移到了堆
具体的变化请自行参考JVM相关资料
String a = "a";String b = "a";String c = new String("b");String d = new String("a");String e = new String("b");
直接赋值
首先在常量池判断是否存在a,如果不存在则在常量池开辟一块空间存放a,如果存在则不用开辟空间。
然后在栈中开辟一块空间存放常量池中a的内存地址,并且命名为a。
通过new
首先在常量池判断是否存在b,如果不存在则在常量池开辟一块空间存放b,如果存在则不用开辟空间。
然后在内存堆中开辟一块空间存放new出来的对象
然后在栈中开辟一块空间存放内存堆中a的内存地址,并且命名为c。
关于堆里面的String对象和常量池里面的String常量之间的的联系,一脸懵逼,望高手解答
String 的比较主要是 == equals
通过这俩个判断可以验证上面的问题
System.out.println(a == b); System.out.println(a == d); System.out.println(c == e); System.out.println(a.equals(b)); System.out.println(a.equals(d)); System.out.println(c.equals(e));
输出
truefalsefalsetruetruetrue
关于 == 和 equals 请参考Java equals == 简单分析
a与b都是存放常量池的内存地址,所以a与b == 返回 true
a与b内容一致,所以a与b equals 返回true
d存放的是堆的内存地址,所以a与d == 返回 false
a与d内容一致,所以a与b equals 返回true
c与e存放的是不同的堆的内存地址,所以c与e == 返回 false
c与e内容一致,所以a与b equals 返回true
String StringBuffer StringBuilder
基于 String 的不可变行带来的效率问题引出来
StringBuffer StringBuilder
后俩者的主要是区别,可以直接通过代码得到
StringBuffer
public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; }
StringBuilder
public StringBuilder append(String str) { super.append(str); return this; }
分析
String通过“+”进行操作的时候,由于String是不可变的,所以每次操作都会产生一个新的String对象,依次类推,最后会产生一大堆需要垃圾回收的中间对象。
这个要说明一个问题,就是本身编译器是使用StringBuilder对代码进行了优化了。但是还是不是最优的,可以通过 javap 进行查看
public String stringAppend() { String result = ""; for (int i = 0; i < 10; i++) { result += String.valueOf(i); } return result; } public String sbAppend() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10; i++) { sb.append(i); } return sb.toString(); }
public java.lang.String stringAppend(); Code: 0: ldc #2 // String 2: astore_1 3: iconst_0 4: istore_2 5: iload_2 6: bipush 10 8: if_icmpge 39 // 开始一个循环体 11: new #3 // class java/lang/StringBuilder 14: dup 15: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V // 这个地方很关键 在循环体里面去构造对象 18: aload_1 19: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: iload_2 23: invokestatic #6 // Method java/lang/String.valueOf:(I)Ljava/lang/String; 26: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 29: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 32: astore_1 33: iinc 2, 1 36: goto 5 // 结束循环体 39: aload_1 40: areturn
public java.lang.String sbAppend(); Code: 0: new #3 // class java/lang/StringBuilder 3: dup 4: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V // 只构造一次对象 7: astore_1 8: iconst_0 9: istore_2 10: iload_2 11: bipush 10 13: if_icmpge 28 16: aload_1 17: iload_2 18: invokevirtual #8 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 21: pop 22: iinc 2, 1 25: goto 10 28: aload_1 29: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 32: areturn
我只能说显而易见了
- string 简单的分析
- String 简单分析
- Java 中 String 与 StringBuffer 简单的源代码分析
- string分析
- String分析
- String分析
- Java基础之jdk1.8 JVM内存模型简述,含String常量池简单分析
- string 简单参数用法
- 简单的String类
- 简单的string实现
- string的简单用法
- string的简单实现
- string简单小结
- String简单使用
- 简单的string 类
- C++ string 简单实现
- String内存简单介绍
- 实现简单String类
- golang基础-终端读(Scanln\bufio)、bufio文件读、、ioutil读读压缩、缓冲区读写、文件写入、文件拷贝
- MATLAB基础
- 11月已到,会分叉出第三种 “比特币” 吗?
- Java学习——赋值运算符
- 题解:第一次测试(2,3)
- String 简单分析
- transform函数转换大小写
- K-近邻算法
- 异常
- EXPLAIN分析SQL的执行计划
- 吴恩达Coursera深度学习课程 DeepLearning.ai 编程作业——Initialize parameter(2-1.1)
- HTML知识体系图谱
- CSS知识体系图谱
- oracle安装好了,在sql plus 要输入用户名和密码? 用户名和密码是多少???