共计 4283 个字符,预计需要花费 11 分钟才能阅读完成。
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—————-
正文完