String(二) 源码分析

String(二) 源码分析


以下所有源码都是基于,jdk1.8的版本

String实现的接口

image_1cl67gv1rl7s16h31p3b14j01ak59.png-13.1kB

  • java.io.Serializable 序列化接口可以被序列化与反序列化
  • Comparable<String> 这个接口主要比较大小
  • CharSequence CharSequence就是字符序列,而String的值是只读序列

String的属性

  在Java中String是一个对象,并不是Java里面的基础数据类型。

image_1cl682ccb1ujnsltg0u1o3k10f9m.png-19.9kB

private final char value[]:表示String的由一个final修身的 char value[] 组成的。
private int hash: 表示String对象的hashCode的值,当String创建时栈里面存放的是String的hashCode。

String并没有length属性

  String没有length属性,而是有length()方法,length()方法返回的char数组的长度。
image_1cl68gud8n6i13dluqf1f7ep1g1g.png-22.3kB

intern()解析

  String的 intern() f查看源码(jdk1.8),对它的描述:

   new String(“qwer”).intern()调用时,会先去常量常量池里面查找”qwer”,如果查找到相同”qwer”就不会创建新的”qwer”,而只使用常量池里面的”qwwer”,从而保证这个字符串在常量池里面的唯一性。

下面的一道经典的面试题:

public class StringEqTest {
    public static void main(String[] args) {
        String s1 = "qwer";
        String s2 = "qw";
        String s3 = "er";
        String s0 = s2+s3;
        String s4 = new String("qwer");
        String s5 = new String("qwer");
        String s6 = new String("qwer").intern();
        String s7 = new String("qwer").intern();

        System.out.println("s1==s0:\t"+(s1 == s0));
        System.out.println("s1==s4:\t"+(s1 == s4));
        System.out.println("s4==s5:\t"+(s4==s5));
        System.out.println("s5==s6:\t"+(s5==s6));
        System.out.println("s1==s6:\t"+(s1==s6));
        System.out.println("s6==s7:\t"+(s6==s7));


    }
}

来看看结果是不是和你想的一样呢?(这里使用的JDK1.8)

image_1cl3egmsn1ma0p8m1bpp1v2c19q99.png-13.9kB

解析:

  1. s1 == s0 —-> false 这是s0 = s2+s3 这里使用java的重载符号+,这反编译过程中+会调用StringBuildappend()方法拼接字符串,最后返回to.String的结果。所以为false。
  2. s1 == s4 —-> false s4 的new创建了一个新的对象
  3. s4 == s5 —-> false 分别创建了两个新的对象
  4. s5 == s6 —-> false 这里要先分析String().intern()方法,这个方法在运行时会查找常量池里面是否有”qwer”字符串,若常量池里面有相同的字符串就使用常量池里面的,反之就创建一个新的字符串。s6在常量池里面查找到”qwer”,而s5为new所有false。
  5. s1==s6 —–>true ,s6常量池查找到”qwer”,而s1是在常量池里面”qwer”的创建者,所以true。
  6. s6==s7 ——>true 都是常量池里面的

猜你喜欢

转载自blog.csdn.net/zx6571269/article/details/81812096