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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 小周务商 金牌黑马   /  2014-5-5 11:04  /  1535 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

                String s1  = new String("11");
                String s2  = new String("11");
                System.out.println(s1 == s2);//false
                String s3 = "22";
                String s4 = "22";
                System.out.println(s3 == s4);//true

8 个回复

倒序浏览
每一个 new 的动作都会 在内存中 新 生成一个对象, 多以在 new String时 ,生成了两个实例对象。 而 s1 和 s2 是对 对象的引用, 也就是存储的是 对象的地址。 s1 和 s2 指向的是不同的对象,所以 他们中存储的地址是不相同的,所以 用 == 的结果是 false 。 这里有一点 要注意的 == 和 equlas的区别。 对于 代码段中出现的 字符串 像楼主 声明的 String s = “22”这种 编译器 在编译的时候 会替你生成 字符串的 对象。 也是用 new 的方法。但是 他有个特点, 如果 代码中多处 使用了 相同的 字符串,那 编译器 就对这些 字符串 创建一个 String 的对象,而不是 多个。

评分

参与人数 1技术分 +1 收起 理由
zzkang0206 + 1

查看全部评分

回复 使用道具 举报
因为s1和s2是new出来了两个不同的对象。而s3和s4它们是直接存储在字符缓冲区中的。s3已经存储到了缓冲区中。而s4是直接取出来复用的。所以s1和s2为false,而s3和s4是true.
回复 使用道具 举报
因为 第一个两个的物理地址是不同的 第二个都是给死的值  
回复 使用道具 举报
明白了。谢谢。
回复 使用道具 举报
这里只告诉你答案也对你没什么帮助,我觉得你有必要了解一下字符串常量池的概念。下面是我的笔记,我也就不一个字一个字打了,直接复制给你看看:
看看String类的源码实现,这是从本质上认识String类的根本出发点。从中可以看到:
1、String类是final的,不可被继承。public final class String。
2、String类是的本质是字符数组char[], 并且其值不可改变。private final char value[];
然后打开String类的API文档,可以发现:
3、String类对象有个特殊的创建的方式,就是直接指定比如String x = "abc","abc"就表示一个字符串对象。而x是"abc"对象的地址,也叫做"abc"对象的引用。
4、String对象可以通过“+”串联。串联后会生成新的字符串。也可以通过concat()来串联,这个后面会讲述。
5、Java运行时会维护一个String Pool(String池),JavaDoc翻译很模糊“字符串缓冲区”。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区。
6、创建字符串的方式很多,归纳起来有三类:
其一,使用new关键字创建字符串,比如String s1 = new String("abc");
其二,直接指定。比如String s2 = "abc";
其三,使用串联生成新的字符串。比如String s3 = "ab" + "c";

再看你的问题:
首先你要知道每一个new出来的对象都会被保存在堆内存中。语句String s1  = new String("11");和String s2  = new String("11");new出来两个对象,这两个对象的内容虽然一样,但是在堆内存中的地址却是不一样的,也就是说,引用s1和s2所指向的地址是不一样的。
其次你要知道的是“==”所比较的是什么。这里双等号比较的是s1和s2两个引用所指向的地址,而不是他们所代表的对象的内容。所以第一个是false。


至于第二个,明白了字符串常量池,你也就明白了原因。 String s3 = “22“;  String s4 = “22“;这里字符串"22"是保存在字符串常量池中的,而常量池中的内容是不重复的。s3和s4都指向"22",当然他们的地址也就想同啦。
回复 使用道具 举报
  1. String s1  = new String("11");
  2.                 String s2  = new String("11");
  3.                 System.out.println(s1 == s2);//false
  4.                 String s3 = "22";
  5.                 String s4 = "22";
  6.                 System.out.println(s3 == s4);//true
复制代码

1,s1和s2是两个不同对象的不同引用,他们分别指向各自的对象。分别储存着对象的储存地址,由于new出来两个不同对象,所以地址当然不同。如果用equals()方法,s1.equals(s2)==true;
2,s3和s4呢,当String s3="22";系统会先在常量池中寻找是否有内容"22"的字符串,没有就会重新建立对象引用s3,并将它指向对象"22";当执行String s4="22"时,系统也会在常量池中寻找是否有内容为"22"的对象,存在,就直接建立对象引用s4指向了对象"22";
3,equals与"=="的区别就是,equals比较的是储存在堆中的数据内容,而“==”比较的是储存在栈中的数据内容。new出来的对象以及数组都是储存在堆中,基本数据类型以及引用型都是储存在栈中。有特例就是:String类复写了equals()方法,它比较的是两个对象中的内容是否相等。“==”一般比较的是数据内容的地址,所以s1!=s2,而s3=s4;equals()比较的是纯属数据内容。
回复 使用道具 举报
你代码中S1和S2是两个新对象,多以是fasle,毕老师在视频中有讲过这个问题
回复 使用道具 举报

  1.                 String s1  = new String("11");
  2.                 String s2  = new String("11");
  3.                 System.out.println(s1 == s2);//false//因为==比较的是两对象的地址是否相同。你创建了两个对象当然不同了,所以是false。如果想得到true,用字符串中的equals方法,它比较的就是值相同.
  4.                 String s3 = "22";
  5.                 String s4 = "22";
  6.                 System.out.println(s3 == s4);//true
复制代码
//这里当当你创建“22”这个字符串常量的时候,他会把他存储在常量池中,第二次用到的时候直接拿来用,所以地址是相同的。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马