A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李凤鸣 中级黑马   /  2012-12-10 12:14  /  2760 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

String s1="abc";
String s2=new String("abc");

课件里讲这两个的区别是:
s1代表一个对象。
s2代表两个对象。

我想问 s2代表的两个对象分别是什么?

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

4 个回复

正序浏览
    首先这当中涉及到了常量池的概念:常量池是指在编译期被确定并被保存在已编译的.class中的一些数据。它包括了类、方法、接口中的常量,也包括字符串常量。如:
                String str1 = "hello";
                String str2 = "hello";
                String str3 = "he"+"llo";
                System.out.println(str1==str2);
                System.out.println(str1==str3);
                System.out.println(new String("hello") == new String("hello"));       //new 创建的两个对象肯定不是同一个对象,所以是false
      结果分别是true、true、false
      java内存中会保留一份字符串常量,str1、str2都是字符串常量在编译期间就已经确定,str3由"he"、"llo"两个字符串常量构成,其本身也是字符串常量,
所以 str3 引用的也是内存中”hello“。而用new String()创建的字符串不是常量,不能再编译期间就能确定。所以new String()创建的对象不会放在常量池中,
他们有自己的地址空间。

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
String s = new String("abc");
首先我们要明白两个概念,引用变量和对象,对象一般通过new在堆中创建,s只是一个引用变量。
所有的字符串都是String对象,由于字符串文字的大量使用,java中为了节省时间,在编译阶段,会把字符串文字放在文字池中,文字池的一个好处就是可以把相同的字符串合并,占用一个空间,我们可以用==判断一下两个引用变量是否指向了一个地址即一个对象
public class Demo02 {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String s1 ="abc";
        String s2 = "abc" ;
        if( s1 == s2 ) System.out.println("s1,s2 refer to the same object");
        else System.out.println("trouble");
    }
}
可以看出指向了一个对象,即文字池中保存了一个对象。
二、String s = new String("abc")实际上是"abc"本身就是文字池中的一个对象,在运行 new String()时,把文字池即pool中的字符串"abc"复制到堆中,并把这个对象的应用交给s,所以创建了两个String对象,一个在pool中,一个在堆中。

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
String s1 = “abc”; 和 String s2 = new String(“abc”);的区别:
String s1 = “abc”;(采用字面值方式赋值)
1) 查找String Pool中是否存在“abc”这个对象,如果不存在,则在String Pool中创建一个“abc”对象,然后将String Pool中的这个“abc”对象的地址返回来,赋给引用变量s1,这样s1会指向String Pool中的这个“abc”字符串对象
2) 如果存在,则不创建任何对象,直接将String Pool中的这个“abc”对象地址返回来,赋给s1引用。
String s2 = new String(“abc”);
1) 首先在String Pool(字符串常量池)中查找有没有“abc”这个字符串对象,如果有,则不在String Pool中再去创建“abc”这个对象了,直接在堆中(heap)中创建一个“abc”字符串对象,然后将堆中的这个“abc”对象的地址返回来,赋给s2引用,导致s2指向了堆中创建的这个“abc”字符串对象。
2) 如果没有,则首先在String Pool中创建一个“abc“对象,然后再在堆中(heap)创建一个”abc“对象,然后将堆中的这个”abc“对象的地址返回来,赋给s2引用,导致s2指向了堆中所创建的这个”abc“对象。

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马