黑马程序员技术交流社区

标题: String s = new String("abc");你真的了解吗??? [打印本页]

作者: 何洪森    时间: 2012-2-6 16:17
标题: String s = new String("abc");你真的了解吗???
下面是我在网上面看到的,感觉很好分享一下。
"abc"与new String("abc");
    经常会问到的面试题:String s = new String("abc");创建了几个String Object?【如这里创建了多少对象? 和一道小小的面试题 】

    这个问题比较简单,涉及的知识点包括:

引用变量与对象的区别;
字符串文字"abc"是一个String对象;
文字池[pool of literal strings]和堆[heap]中的字符串对象。
    一、引用变量与对象:除了一些早期的Java书籍和现在的垃圾书籍,人们都可以从中比较清楚地学习到两者的区别。A aa;语句声明一个类A的引用变量aa[我常常称之为句柄],而对象一般通过new创建。所以题目中s仅仅是一个引用变量,它不是对象。[ref 句柄、引用与对象]

    二、Java中所有的字符串文字[字符串常量]都是一个String的对象。有人[特别是C程序员]在一些场合喜欢把字符串"当作/看成"字符数组,这也没有办法,因为字符串与字符数组存在一些内在的联系。事实上,它与字符数组是两种完全不同的对象。

        System.out.println("Hello".length());
        char[] cc={'H','i'};
        System.out.println(cc.length);

    三、字符串对象的创建:由于字符串对象的大量使用[它是一个对象,一般而言对象总是在heap分配内存],Java中为了节省内存空间和运行时间[如比较字符串时,==比equals()快],在编译阶段就把所有的字符串文字放到一个文字池[pool of literal strings]中,而运行时文字池成为常量池的一部分。文字池的好处,就是该池中所有相同的字符串常量被合并,只占用一个空间。我们知道,对两个引用变量,使用==判断它们的值[引用]是否相等,即指向同一个对象:

String s1 = "abc" ;
String s2 = "abc" ;
if( s1 == s2 )
     System.out.println("s1,s2 refer to the same object");
else
     System.out.println("trouble");

    这里的输出显示,两个字符串文字保存为一个对象。就是说,上面的代码只在pool中创建了一个String对象。

    现在看String s = new String("abc");语句,这里"abc"本身就是pool中的一个对象,而在运行时执行new String()时,将pool中的对象复制一份放到heap中,并且把heap中的这个对象的引用交给s持有。ok,这条语句就创建了2个String对象。

String s1 = new String("abc") ;String s2 = new String("abc") ;if( s1 == s2 ){ //不会执行的语句}

    这时用==判断就可知,虽然两个对象的"内容"相同[equals()判断],但两个引用变量所持有的引用不同,

    BTW:上面的代码创建了几个String Object? [三个,pool中一个,heap中2个。]
引用和对象的关系,String s ="abc";和String s = new String("abc");语句产生了几个对象,相信大家也都明白了吧。
作者: 易伟    时间: 2012-2-6 16:29
赞一个,很详细。
作者: 衣服    时间: 2012-2-6 16:34
赞一个

作者: 最初的理想    时间: 2012-2-6 16:59
赞一个

作者: 李晓俊老师    时间: 2012-2-6 17:02
结论是:String s = new String("abc");创建了2个String对象。哈哈。''abc''是一个,而s又指向了一个被复制后的''abc''
作者: 黑马唐浩    时间: 2012-2-6 18:31
这个,毕老师在视频里讲过啊。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2