String类的详细解析

今天又重新学习了一下String类,看来以前学的还是不扎实啊,下面说一说吧。

下面来看一个例子:

 String s1 = new String("hello");
        String s2 = new String("hello");
        String s31 = s2;
        String s32 = new String(s2);
       
        String s4 = "hello";
        String s5 = "hello";
        String s61 = s5;
 
        System.out.println(s1.equals(s2));//true
        System.out.println(s1.equals(s31));//true
        System.out.println(s1.equals("hello"));//true
        System.out.println();
       
        System.out.println(s1 == s2);//false
        System.out.println(s1 == s31);//false
        System.out.println(s1 == "hello");//false
        System.out.println();
        System.out.println(s2 == s31);//true
        System.out.println(s2 == s32);//false
        System.out.println(s32 == "hello");//false
        System.out.println();
       
        System.out.println(s4.equals(s5));//true
        System.out.println(s4.equals(s61));//true
        System.out.println(s4.equals("hello"));//true
        System.out.println();
       
        System.out.println(s4 == s5);//true
        System.out.println(s4 == s61);//true
        System.out.println(s4 == "hello");//true
        System.out.println();
       
        StringBuffer sb1 = new StringBuffer("hello");
        StringBuffer sb2 = new StringBuffer("hello");
       
        System.out.println(sb1.equals(sb2));//false
        System.out.println(sb1 == sb2);//false


 “因为String太过常用,JAVA类库的设计者在实现时做了个小小的变化,即采用了享元模式,每当生成一个新内容的字符串时,他们都被添加到一 个共享池中,当第二次再次生成同样内容的字符串实例时,就共享此对象,而不是创建一个新对象,这样的做法仅仅适合于通过=符号进行的初始化

Java中,“==”运算符用来比较两个引用以查看它们是否指向同一个内存对象。而对于String实例,运行时状态会尽可能地确保任意两个具有相同字符信息的String字面值指向同一个内部对象。此过程称为驻留(interning),但是它并不有助于每个String的比较。一个原因是垃圾收集器线程删除了驻留值,另一个原因是String所在的位置可能被一个由String构造函数创建的新实例占用。如果是这样,“==”将总是返回false。

 

StringBuffer的情况:

        StringBuffer e = new StringBuffer("hjy");
        StringBuffer f = new StringBuffer("hjy");
        System.out.println( e==f );//false
        System.out.println( e.equals(f));//false

StringBuffer从Object里继承了Equals(),所以仍是比较内存的,和==一样,e和f内存地址不同,所以都返回false。



*******************************************************************************************************************************************************************

Continue..........


一切从String str = new String("abc")说起...

    问上面这行代码创建了几个String对象?

    我刚开始很自然的觉得应该是创建了一个String对象,后来查阅资料,才发现,实际上创建了两个String对象。下面说明为什么创建了两个String对象。

    首先,来了解一下Java中的字符串驻留池的概念。JVM为了提高性能,将一下两种形式的字符串放在一个称之为字符串驻留池的内存块中:

    形式一:String str = "abc";

    形式二:"abc"

    其实,形式一和形式二都是字符串的字面常量。所以,可以这样理解,即把字符串的字面常量都放在了字符串驻留池中。对形式一来说,str其实就是引用的字符串驻留池中"abc"这个String对象。

    如果有如下的两行代码:

    String str1 = "abc";

    String str2 = "abc";

    那么,上面的两行代码创建了几个String对象?答案是一个。根据我们刚才所述,那么第一行语句将在池中创建一个String对象,第二行会先在池中寻找是否有值与"abc"相同的String对象,如果有,就直接引用,没有这在池中新建String对象。这下,就明白了为什么上面的两行语句仅仅创建了一个String对象。

    然后,让我们来看一看String str = new String("abc")。我们先不讨论到底创建了几个String对象。我们在这里,比较一下这种new的方式和上面的直接赋值方式两种创建String对象的不同,直接赋值的方式是在字符串驻留池中创建对象,但new这种方式是在堆中创建对象。即,new创建的String对象是不会放入字符串驻留池中的。如果一定要把某个通过new创建的字符串对象放入驻留池,可以使用intern()方法。如String strt = str.intern(),将把str的值放在驻留池中(当然,是在驻留池原来没有这个值对应的String对象的情况下),并返回驻留池中String对象的引用。

    现在,可以分析String str = new String("abc");创建了几个String对象了:)很明显,传入的"abc"字符串字面常量在驻留池中创建了一个对象,new操作符在堆中创建了一个对象,所以,一共创建了两个String对象



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值