在Java中,字符串存放在常量池中,new方法创建的对象存放在heap(堆内存)中。
String a = "abc";//常量池
String b = new String("abc");//heap
a==b;//false
a.equal(b);//true
1、Constant Pool 常量池的概念
在Java 编译好的class文件中,有个区域被称为Constant Pool,它是一个由数组组成的表,类型为cp_info constant_pool[],用来存储程序中使用的各种常量,包括Class、String、Integer等各种基本的Java数据类型。
String Pool是Constant Pool中存储String常量的区域,对于值相同的String常量,在Constant Pool中只会创建一个,所以在编译好的class文件中,只能找到一个对该常量的表示。
在程序执行的时候,Constant Pool会存储在Method Area中,而不是堆中。对于“”,内容为空的字符串常量,创建一个长度为0,内容为空的字符串放在Constant Pool中,而且Constant Pool可以在运行期动态扩展。
2、String 类
- String 使用private final char value[]来实现字符串的存储。即String对象创建之后,就不能在修改此对象中存储的字符串的内容。【String类型是不可变的】
- String类有一个特殊的创建方法,使用“”双引号来创建。
new String("ABC");
,实际上创建了2个对象,一个是ABC通过“”创建,另一个是new创建,他们的创建时期不同,前者在编译期,后者在运行期。 - Java中 String类型重载了+操作符,可以直接使用+来拼接字符串
- 运行期调用String类的intern()方法,可以向String Pool中动态添加对象
- String的创建方法有:1.” ” 2. new String() 3.new String(“abc”)以及其他一些重载的构造函数 4.+进行拼接
package T617;
/**
* Created by Promacanthus on 2017/6/17.
*/
public class T4 {
public static void main(String[] args) {
String string1 = "abcde";
String string2 = "abcde";
String string3 = new String("abcde");
String string4 = "ab";
String string5 = "cde";
String string6 = string4 + string5;
string1 = string2;//true
string1 = string3;//false
string3.intern();
string1 = string3;//true
string1 = string6;//true
}
}
3、String和StringBuffer的区别
3-1、String的创建:
String s = "hello";
JVM首先根据内容查找对象,没找到则在heap上创建新对象,并赋予s,否则使用已经存在的。String s = new String("hello");
JVM直接在heap上创建新的对象,所以在heap中会出现内容一样地址不同的String对象
3-2、String的比较:
- == 比较地址
- equals 比较内容
3-3、String和StringBuffer效率比较
String 比 StringBuffer快
String a = "a"+"b";
StringBuffer a = new String.append("a").append("b"):
后者比前者快
StringBuffer a = new StringBuffer();
for(int i - 0; i<5000;i++){
a.append("a"):
}
StringBuffer a = new StringBuffer(250000);
for(int i - 0; i<5000;i++){
a.append("a"):
}
因为StringBuffer内部实现的是char数组,默认初始长度为16,每当字符串长度大于char数组长度的时候,JVM会构造更大的新数组,并将原先的数组内容复制到新数组中
3-4、StringBuffer总结
- 不能简单的任务append()效率好与+
- 不要使用new 创建String
- 注意intern()的使用
- 子啊编译器能够确定字符串的情况下,+效率高
- 避免使用+=来构造字符串
- 在声明StringBuffer的到时候,指定合适的capacity,不要使用默认值
- 注意:
String s = "a"+"b";
和String s ="a"; s +="b";
后者开辟了2段内存
3-5、StringBuilder
StringBuilder和StringBuffer是一样的,都是字符串变量,唯一的区别是前者不安全,后者线程安全。
在单线程的情况下,通常默认使用StringBuilder,因为这个最快。
- 如果要操作少量的数据用 = String
- 单线程操作字符串缓冲区下操作大量数据 = StringBuilder
- 多线程操作字符串缓冲区下操作大量数据 = StringBuffer
三者在执行速度方面的比较:StringBuilder > StringBuffer > String
String:字符串常量
StringBuffer:字符串变量
StringBuilder:字符串变量