
一、字符串常量池
public static void main(String[] args) {
String s1 = "abc"; String s2 = "abc"; String s3 = new String("abc"); String s4 = new String("abc"); System.out.println(s1 == s2); System.out.println(s1 == s3); System.out.println(s3 == s4); }
1.使用字符常量直接赋值:
public static void main(String[] args) {
String s1 = "abc"; String s2 = "abc"; System.out.println(s1 == s2); }

在直接用字面常量赋值String时,先在常量池里找,是否有这个字符串,如果没有则创建,我们发现常量池并没有abc,所以我们创建一个“abc”。

当第二次创建”abc”字符串赋给s2时直接指向就行.

s1和s2指向的是同一块引用,所以s1 == s2。
2.通过new创建String类对象:

只要new对象,它的引用就是唯一的.
使用常量串创建String类型对象的效率更高,而且更节省空间。
3.intern方法:
intern 是一个native方法(Native方法指:底层使用C++实现的,看不到其实现的源代码),该方法的作用是手动将创建的String对象添加到常量池中。
public static void main(String[] args) {
char[] ch = new char[]{
'a','b','c'}; String s1 = new String(ch); String s2 = "abc"; System.out.println(s1 == s2); }

我们可见s1 和 s2指向不同的引用
public static void main(String[] args) {
char[] ch = new char[]{
'a','b','c'}; String s1 = new String(ch); s1.intern(); String s2 = "abc"; System.out.println(s1 == s2); }
二、字符串的不可变性
- 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.
- 不可变对象是线程安全的.
- 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中.
三、字符串修改
字符串是不能修改的,每次修改都会创建新对象,效率非常低下.
public static void main(String[] args) {
String str = "wo"+"yao"+"jin"+"da"+"chang"; System.out.println(str); }

当然是可以正常输出的,我们看一下汇编.

我们会发现创建了许多StringBuilder对象,去拼接字符串,这样效率十分低下。
public static void main(String[] args) {
long start = System.currentTimeMillis(); String s = ""; for(int i = 0; i < 10000; ++i){
s += i; } long end = System.currentTimeMillis(); System.out.println(end - start); start = System.currentTimeMillis(); StringBuffer sbf = new StringBuffer(""); for(int i = 0; i < 10000; ++i){
sbf.append(i); } end = System.currentTimeMillis(); System.out.println(end - start); start = System.currentTimeMillis(); StringBuilder sbd = new StringBuilder(); for(int i = 0; i < 10000; ++i){
sbd.append(i); } end = System.currentTimeMillis(); System.out.println(end - start); }

我们发现在对String进行修改时,String与StringBuffer和StringBuilder相差几百倍.
四、StringBuilder与StringBuffer的方法

这里都是StringBuffer和StringBuilder的一些方法.
1.append
拼接字符串
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("wo yao jin da chang!"); System.out.println(stringBuilder); }

2.reverse
字符串逆置
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder("abcd"); stringBuilder.reverse(); System.out.println(stringBuilder); }

3.delete
删除指定范围内的字符
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder("abcd"); stringBuilder.delete(0,2); System.out.println(stringBuilder); }

String与StringBuilder相互转换:
String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可
以修改。频繁修改字符串的情况考虑使用StringBuilder
1.String变为StringBuilder
public static void main(String[] args) {
//调用StringBuilder构造方法 String str = "abc"; StringBuilder stringBuilder = new StringBuilder(str); }
public static void main(String[] args) {
//append拼接字符串 String str = "abc"; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(str); System.out.println(stringBuilder); }

1.StringBuilder变为String

我们可以看一下StringBuilder的toString()方法返回的是一个String对象.
public static void main(String[] args) {
//StringBuilder的toString()方法 StringBuilder stringBuilder = new StringBuilder("abc"); String str = stringBuilder.toString(); System.out.println(str); }

四、StringBuilder与StringBuffer区别
String、StringBuffer、StringBuilder的区别:
1.String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
2.StringBuffer与StringBuilder大部分功能是相似的
3.StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

StringBuffer中的每个方法加入了synchronized,它就相当于是一把锁,只要有第一个人访问这个方法,那么这个方法就只能等第一个人访问完成之后,剩下的人才能访问.
String str = new String("abc"); String str = new String("ab") + new String("c");
这项行代码分别创建多少个对象?(之前常量池没有存储过任何字符串)
- 2个
- 6个
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/216391.html原文链接:https://javaforall.net
