java.lang.String
- String类型的特点:
1)String类型是不能被继承的;
2)String类型的对象是不可变的,也就是说咱们每次批改字符串都是产生了新的对象;
3)因为String类型的对象是不可变的,使得咱们把一些字符串存到常量池里,常量池中的对象是能够共享的; - HotSpot虚拟机的常量池在哪里呢?
JDK 1.6及之前 常量池是在办法区里的;
JDK 1.7在堆中独自划分了一块用来存储常量;
JDK 1.8从堆中拿进去放到了元空间Metaspace里,元空间在本地内存里; - String对象的底层存储:
JDK1.9之前是通过char[]来存储的;
JDK1.9之后是通过byte[]存储的; - String对象是怎么实现不可变的?
1)底层char[]是final润饰的,也就管制了该字符串对象长度的不可变;
2)底层的char[]是公有的,程序员是无奈间接操作的,并且String类也没有提供批改办法,String类提供的所有办法都是返回新的对象; 字符串的比拟问题:
1)== 比拟对象的地址://在常量池中雷同的字符串常量比拟才会返回true:public void cmp01(){ String s1 = "zzn"; String s2 = "zzn"; System.out.println(s1==s2);//true}
//在堆中的字符串和在常量池中的字符串==比拟是不会相等的:public void cmp02(){ String s1 = new String("zzn"); String s2 = "zzn"; System.out.println(s1==s2);//false}
//在堆中的两个字符串==比拟也是不会相等的:public void cmp03(){ String s1 = new String("zzn"); String s2 = new String("zzn"); System.out.println(s1==s2);//false}
2)equals()办法比拟两个对象的内容:只有是内容雷同不论是在常量池还是堆都是true;
public void cmp01(){ String s1 = "zzn"; String s2 = "zzn"; System.out.println(s1.equals(s2));//true }
public void cmp02(){ String s1 = new String("zzn"); String s2 = "zzn"; System.out.println(s1.equals(s2));//true}
public void cmp03(){ String s1 = new String("zzn"); String s2 = new String("zzn"); System.out.println(s1.equals(s2));//true}
3)equalsIgnoreCase()办法,疏忽大小写比拟内容,不论是在堆还是常量池只有内容上只有大小写差异就会返回true;
public void cmp01(){ String s1 = "zzn"; String s2 = "ZZN"; System.out.println(s1.equalsIgnoreCase(s2));//true}
public void cmp02(){ String s1 = new String("zzn"); String s2 = "ZZN"; System.out.println(s1.equalsIgnoreCase(s2));//true }
public void cmp03(){ String s1 = new String("ZZN"); String s2 = new String("zzn"); System.out.println(s1.equalsIgnoreCase(s2));//true}
4)字符串比拟大小:
·天然排序:实现了java.lang.comparable接口://辨别大小写,String类实现了java.lang.comparable接口中的public int compareTo(T o);办法; public void cmp01(){ String s1 = "zzna"; String s2 = "ZZN"; if (s1.compareTo(s2) > 0){ System.out.println(s1 + " > " + s2); }else if (s1.compareTo(s2) == 0){ System.out.println(s1 + " = " + s2); }else if (s1.compareTo(s2) < 0){ System.out.println(s1 + " < " + s2); } //后果:zzna > ZZN }
//不辨别大小写,String类本人提供了public int compareToIgnoreCase(String str)办法;public void cmp01(){ String s1 = "zzn"; String s2 = "ZZN"; if (s1.compareToIgnoreCase(s2) > 0){ System.out.println(s1 + " > " + s2); }else if (s1.compareToIgnoreCase(s2) == 0){ System.out.println(s1 + " = " + s2); }else if (s1.compareToIgnoreCase(s2) < 0){ System.out.println(s1 + " < " + s2); }// 后果:zzn = ZZN}
·定制排序:Collator做比拟器;
public static void main(String[] args) { String[] array = {"周震南","薛之谦","白敬亭"}; // getInstance();获取以后默认语言环境的Collator。 // getInstance(Locale.CHINA);指定语言环境为中文取得Collator比拟器 Arrays.sort(array, Collator.getInstance(Locale.CHINA)); System.out.println(Arrays.toString(array));}
- 字符串有几个对象问题;
1)String str = "zzn";只有常量池中的一个字符串对象;
2)string str = new String("zzn");在堆中有一个new进去的对象,在String pool中有一个字符串常量对象;
3)String str1 = new String("zzn");
String str2 = new String("zzn");在堆中有2个new进去的String对象,在String pool中有一个字符串常量对象(共享的); 对于拼接后果在堆还是在 String pool的问题:
1)常量 + 常量 在Spring pool中;
2)常量 + 变量 在堆中;
3)变量 + 变量 在堆中;
4)**.intern() 在String pool中;public static void main(String[] args) { String s1 = "hello"; String s2 = "world!"; String s3 = "helloworld!"; // 常量变量拼接后果在堆中; String str1 = s1 + "world!"; // 变量变量拼接后果在堆中; String str2 = s1 + s2; // 常量常量拼接后果在String pool中; String str3 = "hello" + "world!"; System.out.println(s3==str1);//false System.out.println(s3==str2);//false System.out.println(s3==str3);//true } --------------------------------------------------------------------------------- public void test02() { final String s1 = "hello"; String s2 = "world!"; String s3 = "helloworld!"; // 被final润饰的s1也是字符串常量,常量常量拼接后果在String pool中; String str1 = s1 + "world!"; // 变量常量拼接后果在堆中; String str2 = s1 + s2; // 常量常量拼接后果在String pool中; String str3 = "hello" + "world!"; System.out.println(s3==str1);//true System.out.println(s3==str2);//false System.out.println(s3==str3);//true } --------------------------------------------------------------------------------- public void test03() { final String s1 = "hello"; String s2 = "world!"; String s3 = "helloworld!"; // 被final润饰的s1也是字符串常量,常量常量拼接后果在String pool中; String str1 = s1 + "world!"; // 用intern()办法把拼接的后果放到Spring pool中; String str2 = (s1 + s2).intern(); // 常量常量拼接后果在String pool中; String str3 = "hello" + "world!"; System.out.println(s3==str1);//true System.out.println(s3==str2);//true System.out.println(s3==str3);//true }
对于空字符串的问题:
1)哪些才是空字符串对象?public void nullString01(){ String s1;//局部变量未初始化 String s2 = null;//初始化为null,java.lang.NullPointerException String s3 = "";// String pool中的空字符串常量对象; String s4 = new String();//堆中的空字符串对象 String s5 = new String("");//一共两个对象 堆中的String对象,String pool中的空字符串常量对象;}
--------继续更新------------P113-t154----------------