| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 922 人关注过本帖
标题:相信大家看了它,以后对Java字符串问题总是信心百倍
只看楼主 加入收藏
baifenghan
Rank: 8Rank: 8
等 级:贵宾
威 望:10
帖 子:258
专家分:952
注 册:2006-3-17
结帖率:33.33%
收藏
已结贴  问题点数:20 回复次数:6 
相信大家看了它,以后对Java字符串问题总是信心百倍
总结了下关于那些总是说不尽的String问题,目的是让大家彻底告别String的噩梦,彻底理解String的本质。
package stringtest;

public class StringDeep {
   
    public static void main(String[] args) {
        /**
         * 测试一
         *
         * */
        //1.下面三行代码的运行分别创建了几个对象?
        String s1 = new String("abc"); //(1)
        String s2 = "abc";//(2)
       String s3 = new String("abc");//(3)
        
        //2.你认为下面的输出结果应该是什么?
        System.out.println(s1 == s2);//(4)
        System.out.println(s1 == s3);//(5)
        System.out.println(s3 == s2);//(6)
        
        
        /**
         * 测试二
         *
         * */
        String s4 = "hello";
        String s5 = "he";
        String s6 = "llo";
        //3.你认为下面的输出结果应该是什么?
        System.out.println(s4 == "he" + "llo");//(7)
        System.out.println(s4 == "he" + s6);//(8)
        System.out.println(s4 == s5 + "llo");//(9)
        System.out.println(s4 == s5 + s6);//(10)
        
        
        /**
         * 测试三
         *
         * */
        //4.你认为下面的输出结果应该是什么?
        System.out.println(s4 ==  (s5 + s6).intern());//(11)
        
    }

}
上面我写了一小段代码,分成三个部分,其中夹杂了四个问题,如果你可以轻松回答,我想你对String的理解应该是到位的,不能的话,请耐心一起深入学习下String。为了方便,我给上面每一行程序都打上了粉色的行尾标记。
下面我们先回答第一个问题:行(1)生成了两个对象;行(2)生成了0个对象;(3)行生成了一个对象。其对象的内容都是abc。估计很多人已经想反驳这个结论了,那么先看看下面我给出的证据:
1)        API doc关于String的构造方法之一,String(String original)的说明,如下: 初始化一个新创建的 String 对象,表示一个与该参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的一个副本。由于 String 是不可变的,不必使用该构造方法,除非需要 original 的显式副本。大家仔细读一下API的说明就可以清晰的窥见,我用粉色标注的那句,虽然是一个副本,但是的确新创建了一个String对象。
2)        String池的概念:一个初始时为空的字符串池,它由类 String 私有地维护。这句话在intern方法的说明中,这个方法随后说明。可以看出除了在堆中创建一个字符串对象外,还会在字符串池中创建一个字符串对象,它是一个直接量。可以看看下图画出了(1)(2)(3)执行完后的内存结构示意图:
 
                                 
图片附件: 游客没有浏览图片的权限,请 登录注册


如上图, 图片在附件中

         当(1)执行时候,String类先会查找字符串池,是否有abc,发现没有,那么它创建abc,并放入字符串池;并且new关键字的使用,虚拟机又在堆中生成了一个String对象,内容为abc,这样就创建了两个对象,至于引用是s1,是存放在栈中的临时变量,并不是对象。
         当(2)执行时,虚拟机只是在String池中生成一个String对象,它的过程是:先查找字符串池中是否有abc,发现已经有了,所以它直接把这个地址返回给引用s2.注意这里由于(1)的执行,在字符串池中已经有abc了,所以生成0个对象。
         当执行(3)时,首先检查字符串池,发现已经有abc,不用再创建,只是在堆中生成一个新的String对象,所以生成1个对象。

接着回答第二个问题,第一个问题清楚了,这个问题就很好回答,用==比较的是引用,也就是内存地址,那么从上面的分析,从内存结构示意图清晰的看出,三个引用分别指向不同的对象,即有不同的值,所以三个输出都应该是false。

第三个问题中有一个java的约定:
         当使用+这个重载的运算符时候,如果两边有任意一个不是直接量,而是一个引用量,那么虚拟机将新生成一个String对象,并把这个对象作为运算结果。
         当两边都是直接量时候,两者就返回字符串池中的同内容的String对象的引用,作为计算结果。
根据这个约定很显然只有(7)为true,(8)(9)(10)均为false。


最后一个问题,这里牵扯到intern这个方法,看看API的说明:返回字符串对象的规范化表示形式。 一个初始时为空的字符串池,它由类 String 私有地维护。 当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。 它遵循对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。

看看上面的说名,很清晰,通俗点讲:池中如果有和这个String对象内容相同的字符串时候,就返回这个字符串的引用。否则不存在,那么就将此String对象放入池中,并返回该引用。
很显然,在(7)执行完后,字符串池中就有了hello了,而s5+s6的内容就是hello,所以调用intern方法,就是返回和s4值相同的引用了,所以应为true。



总结:
1.      使用String(String original)这个构造函数创建字符串对象实际上生成了两个字符创对象,一个在字符串池中(这里假设池中还没有此字符串),一个在堆中,返回的引用指向堆中那个对象。
2.      使用直接量创建字符串,只会生成一个对象,在字符串池中(这里假设池中还没有此字符串)。如 String str = “just one“;
3.         intern方法返回的是与其内容相同的在字符串池中的那个String对象的引用。

搜索更多相关主题的帖子: 信心百倍 字符 Java 
2010-05-04 18:36
baifenghan
Rank: 8Rank: 8
等 级:贵宾
威 望:10
帖 子:258
专家分:952
注 册:2006-3-17
收藏
得分:0 
自己先顶顶,哈哈,希望大家有时间看看,今天要不是五四青年节,加上女友不在,还真没时间写这么长的东西。再过两年就没有五四过了。
2010-05-04 18:43
xudongcsharp
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:129
专家分:156
注 册:2009-5-31
收藏
得分:10 
呵呵 , 楼主受教了, 谢谢了
2010-05-04 18:52
xudongcsharp
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:129
专家分:156
注 册:2009-5-31
收藏
得分:0 
相当不错的文章,对字符串中“常量池”又有了概念!
谢了楼主!
能否告知一下QQ啊,方便讨教!
2010-05-04 19:01
dadongzicool
Rank: 6Rank: 6
等 级:贵宾
威 望:11
帖 子:209
专家分:474
注 册:2009-3-20
收藏
得分:5 
顶一下

本人出售软件专业毕业设计(包括论文,代码)题目众多,价格从优联系方式:QQ
1635008514(寻找高校代理)
2010-05-04 19:51
冰雪天
Rank: 2
来 自:陕西咸阳
等 级:论坛游民
帖 子:60
专家分:34
注 册:2009-9-4
收藏
得分:5 
学习了,顶一下!

我愛滑板!!!
2010-05-04 23:16
lxh1989
该用户已被删除
收藏
得分:0 
提示: 作者被禁止或删除 内容自动屏蔽
2010-05-05 23:08
快速回复:相信大家看了它,以后对Java字符串问题总是信心百倍
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018451 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved