java-字符串的建立和存储机制

在Java语言这种,字符串起着很是重要的做用,字符串的声明和初始化由如下两种状况: 设计模式

1》对于字符串String s1 = new String("abc")语句与String s2 = new String("abc")语句,存在两种引用对象s1,s2,两个内容相同的字符串对象"abc",他们在内存中的地址是不一样的。只要是用到new总会产生新的对象。 函数

2》对于String s1 = "abc"和String s2 = "abc"语句,在JVM中存在一个字符串池,其中存有不少String对象,而且能够被共享使用,s1,s2引用同一个常连池中的对象,其中String采用Flyweight设计模式,当建立一个字符串常量时,例如String s="abc",会首先在字符串常量池中查找是否存在相同的字符串定义,其判断依据是String对象中的equals方法的返回值。若已经定义,则直接引用其定义,此时不须要建立新的对象;若是没有定义,则首先建立对象,而后把他加入到字符串池中,再将他的引用返回。因为字符串是不可变类,一旦建立好了就不可修改,所以字符串对象能够被共享并且不会引发程序的混乱。 spa

    具体而言: 设计

        String s = "abc";    //把abc放在常量区中,在编译时产生。 对象

        String s = "ab"+"c";    //把“ab”+“c”转换成字符串常量“abc”放在常量区中 内存

        String s =new String("anc");    //在运行时把abc放在堆中 字符串

    例如: string

        String s1 = "abc"; //在常量区中存放了一个"abc"的字符串对象 编译

        String s2 = "abc";//s2引用常量区中的对象,所以不会建立新的对象。 变量

        String s3 = new String("abc");//在堆中建立新的对象

        String s4 = new String("abc");//在堆中又建立一个新的对象

    为了理解方便,能够吧String s = new String("abc")语句的执行分类两个过程;第一个过程就是新建对象的过程,即new String("abc");第二个过程就是赋值过程,即String s=。因为第二个过程仅仅建立了一个字符串类型的变量,将一个字符串对象的引用赋值给s,所以这个过程当中不会建立新的对象。第一个过程new String("abc")调用String类中的构造方法:

    public String(String origin) {

        //body    

    }

    在调用这个构造函数时,传入一个字符串常量,所以语句new String("abc")也就等价于"abc"和new String()两个操做了。若在字符串池中不存在abc,则会建立一个新的字符串常量“abc”,并将其添加到字符串池中;若存在则不建立,而后new String()会在堆中建立一个新的对象,因此s3和s4是指向不一样的String对象,地址天然也就不一样了。如图所示.

    


引伸:对于string类型的变量s,赋值语句s=null与s=""是否相同?

对于赋值语句s=null,其中s是一个字符串类型的引用,它不指向任一个字符串。而赋值语句s=""中的s是一个字符串类型的引用,它指向另外一个字符串(这个字符串的值为"",也就是空字符串),所以两则是不相同的。

常见的笔试题:

new String("abc")建立了几个对象?

answer:一个或者两个。若是常量池中原来有字符串"abc",那么只建立一个对象;若是常量池中没有字符串"abc",那么就建立两个对象(这两个对象分别位于字符串常量池和堆中)。

最后吐槽:为何答,案二字会被审核不经过呢?想不明白

相关文章
相关标签/搜索