String的存储过程

  我们知道字符有两种初始化方式:

    String s1 = “abc”;

     String s2 = new String(”def”);

  这两种有什么区别呢?这时就需要我们看看String的在内存中是怎么存储的了。我们先看下面的图了解其在内存在是怎么存储的:

  首先是String s1 = “abc”;它首先会去常量池去检查是否存在“abc“,如果存在就返回,否则就创建。“abc”的地址给了s1,s1指向了它。而String s2 = new String(”def”);它会先去堆内存中去创建一个new String()对象,然后去常量池检查是否存在”def” 如果存在就返回,否则创建。“def”的地址给了new String(),而new String()自给有一个地址给了s2。这就是字符串的基本存储过程。

  接下来我们看看字符串的一个重要特性:字符串是常量,它们的值在创建之后不能更改。

  如下面一段代码

  

public class TestString {    public static void main(String[] args) {        String s = "abc";        s+="def";        System.out.println(s);    }}

  根据上面的分析我们可以知道 s 最开始是指向”abc”,后面s+=”def”做个一个字符串拼接,而在内存中并没有直接把”def”拼接在“abc”上,而是先开辟了空间存储“def”,最后把abcdef拼接在一起,开辟了第三块空间。通过这个例子我们可以知道不能变的是字符串的值,即“abc”不能改变,而引用是可以改变的。所以最后 s打印出来的值变了,并不是“abc”发生了变化,而是s指向了新的对象“abcdef”。

  接下来我们可以通过1个例子看看

public class TestString {    public static void main(String[] args) {        String s1 = "abc";     String s2 = "abc"        String s3 = new String("abc");     System.out.println(s1==s2)        System.out.println(s1==s3);        System.out.println(s1.equals(s3));            }}

  首先我们要知道==和equals的区别,==比较的是地址,而equals默认比较也是地址,而String重写了equals()方法,比较的是值是否相同。根据上面的理解我们画出内存图

根据上图我们知道了String s1 = “abc”;首先会在常量池中创建“abc”,s1指向此对象,而String s2 = “abc”首先会在常量池中检查发现存在“abc”,所以s2并不会再创建而是直接指向“abc”,而String s3 = new String(“abc”);首先会在堆内存new 一个String对象,然后指向常量池中已经存在的“abc” (不会再创建“abc”),但是new String()给s3是自己的地址,并不是“abc”的地址。所以输出结果为true false true

现在抛出一个问题 String s = “abc”和 String s = new String(”abc”)有什么区别?

答案详情请见下一篇随笔

带上心灵去旅行,以平和的心态看待一切,

String的存储过程

相关文章:

你感兴趣的文章:

标签云: