java.lang.String

  1. String类型的特点:
    1)String类型是不能被继承的;
    2)String类型的对象是不可变的,也就是说咱们每次批改字符串都是产生了新的对象;
    3)因为String类型的对象是不可变的,使得咱们把一些字符串存到常量池里,常量池中的对象是能够共享的;
  2. HotSpot虚拟机的常量池在哪里呢?
    JDK 1.6及之前 常量池是在办法区里的;
    JDK 1.7在堆中独自划分了一块用来存储常量;
    JDK 1.8从堆中拿进去放到了元空间Metaspace里,元空间在本地内存里;
  3. String对象的底层存储:
    JDK1.9之前是通过char[]来存储的;
    JDK1.9之后是通过byte[]存储的;
  4. String对象是怎么实现不可变的?
    1)底层char[]是final润饰的,也就管制了该字符串对象长度的不可变;
    2)底层的char[]是公有的,程序员是无奈间接操作的,并且String类也没有提供批改办法,String类提供的所有办法都是返回新的对象;
  5. 字符串的比拟问题:
    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));}
  6. 字符串有几个对象问题;
    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中有一个字符串常量对象(共享的);
  7. 对于拼接后果在堆还是在 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 }
  8. 对于空字符串的问题:
    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----------------