一、 放到字符串常量池中的字符串有两种情况:
1. 在编译期已经确定的字符串常量,有三种类型,例子如下:
例子1 使用""引起来的字符串
String a = "abcd";
String b = new String("abcd");//仅仅是"abcd"放入了常量池中,b在堆中
例子2 使用+号连接,两边都是使用""引起来的字符串
String a = "ab" + "cd";
例子3 使用+号连接,用final修饰过
final String b = "cd";
String a = "ab" + b;
2.
在运行期使用String类的intern()方法
,例子如下:
String b = new String("abcd");
String c = b.intern();
如果常量池中已经有"abcd",则返回"abcd"的引用,
如果没有,则先在常量池中增加一个"abcd",然后再返回这个引用
问答:
1. String b = new String("abcd");创建了几个对象?
答:2个,第1个在编译期"abcd"被放入了字符串常量池中,
第2个在运行期new String("abcd")创建的String对象被放入了堆heap中
二、关于String类的三个属性:char value[],int offset,int count
char value[] : 字符串在String中存储的时候,底层使用的还是char[]数组
int count : 字符串中一共有多少个字符
int offset : 这个属性指的是字符串开始的位置,默认是0。
由于这个属性的存在,使得有的操作,比如substring(),返回的并不是一个新的String对象,而是原来的字符串,只是offset和count属性改
变了一下。
类似的还有Matcher的group(int)方法,它返回也不是一个新的字符串,而是原字符串 更改了一下offset和count属性。如果原字符串特别大,而
group(int)的结果又需要保存的,那么直接保存group(int)的结果必定会造成大量的内存浪费,所以可以参考使用:
new String( group(int) );这样就
可以只保存group(int)的结果,使原来的字符串,可以被GC掉。
所以鉴于以上原因,String类主要用于保存小的字符串,而比较大的字符串最好使用StringBuilder、StringBuffered。