1.使用原因:
在平时开发中,会使用大量的String类型,如果使用一个字符串,就用new去生成,就会耗内存。sun公司为了解决这个问题就使用字符串池这一概念。
2.字面量/直接量
所谓的直接量就是在定义的时候,等号右边不是另外一个变量,而是是一个实际存在有意义的量。比如;
String s="a";//右边的是直接量
String s1=s;//右边的不是直接量
3.规则:
在Java中,如果我们定义的字符串等于右边是一个直接量,那么该直接量存在字符串池中,如果在定义一个相同直接量,会先到字符串池中去寻找,若存在则直接指向池中的对象,若不存在就创建。
String s="a";
String s1="a";
String s2=new String("a");
有上述代码:首先判断右边赋值的是直接量那么该对象存放在字符串中,桟中存放s指向它的地址,第二条语句也是直面量,先在字符串池中找是否存在该字符串,而找到了,那么桟中存放s1的地址也指向该字符串池中的地址。而第三条语句则就不相同了,因为它是是用new生成的,那么它是在堆区开辟内存的。显然s2指向的地址不同于s,s1.
4、字符串对象有一个很容易出错的特点:
如果你对某个字符串对象进行调用方法的话,不管该对象是在池中还是在堆中,若你调用的
方法没有改变之前的字符串对象的话,那么调用方法之后是不会产生新的对象的,这也是字
符串的一种优化机制
5.intern方法
该方法是人为地把放在堆区中的字符串对象放到字符串池一直优化手段。
代码:(能够全部做对就算掌握了)
package com.string;
public class StringDemo {
public static final String st="ab";
public static final String st1="a";
public static void main(String[] args) {
String s0=st1+"b";
String s="a";//右边的是直接量
String s1=s;//右边的不是直接量
String s2=s+"b";
String s3="12abcd3";
String s4="12abcd3"+"";
String s5="12ab"+"cd3";
String s6="12ab"+"cd"+'3';
String s7='1'+'2'+"ab"+"cd"+'3';
String s8="b";
String s9=new String("abcd2");
String s10=new String("abc"+"d2");
String str1 = "abc";
String str2 = str1.concat("");
String str3 = "abc".substring(0);
System.out.println(s0==st);//true,常量也是字面量,直接量运算时在编译时就进行的
System.out.println(s==s1); //true,在运行期间还是会把s的值赋给s1
System.out.println(st==s2);//false,此时s是变量,相加是在堆区运行,重新在堆区生成一个对象。
System.out.println(s3==s4);//true,直接量运算时在编译时就进行的
System.out.println(s3==s5);//true,
System.out.println(s3==s6);//true,这个与字符串的运算有关,从左往右运算,左边是字符串,就把右边装换位字符串。
System.out.println(s3==s7);//false,类似先前的,先是两个个字符相加记住是ASCLL码值相加,在装换为字符串。
System.out.println(st==(s+s8));//false
System.out.println(s9==s10);//false,两个对象不同,地址肯定不同
System.out.println(str1==str2);//true ,请看4.易错
System.out.println(str1==str3);//true
//intern使用
String a="java";
String b=new String("java");
String c=b.intern();
System.out.println(a==b);//false,请看5
System.out.println(a==c);//true
}
}