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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杨锦 中级黑马   /  2012-8-5 18:09  /  1876 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨锦 于 2012-8-5 19:24 编辑

private static void demo1() {
  String s1 = "abc";
  String s2 = "a" + "bc";  
  System.out.println(s1);
  System.out.println(s2);
  System.out.println(s1.equals(s2));                     
  System.out.println(s1 == s2);                                                 // 为什么这个结果就是 true true

}

private static void demo2() {
  String s1 = "abc";
  String s2 = "a";
  String s3 = "bc";
  String s4 = s2 + s3;  
   System.out.println(s1);
  System.out.println(s4);
  System.out.println(s1.equals(s4));
  System.out.println(s1 == s4);
}                                                                                               //而这个就是true flase

评分

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

查看全部评分

4 个回复

倒序浏览
本帖最后由 郑文博 于 2012-8-5 18:30 编辑

字符传中复写了equals方法,比较的是内容,此程序上下的字符串的内容一样 自然调用equals比较结果是ture了。
下面说“==”,"=="比较的是对象地址值。首先上面程序字符引用类型定义的String s1 = "abc";此时常量池中建立了“abc”把地址值送个s1,再次若如String s2 = "abc";便会到常量池中找,就会把已有的“abc”地址值付给S2。当然这里"a" + "bc"就是“abc”,所以调用s1==s2时便由于地址值一样输出结果即为true了。
然后下面程序中常量池中建立了“a”,“bc”,“abc”分别有个字的地址值指向,String s4 = s2 + s3;便一个新的地址值付给了s4,此时s3的地址值是“abc”对应的,故两者并不相等,便输出结果为flase
回复 使用道具 举报
这个程序JVM使用常量池管理字符串直接量的情形。
常量池:专门用于管理在编译期就被确定并被保存在已编译的.class文件中的一些数据。它包括了
关于类、方法、接口中的常量、还包括字符串常量。

private static void demo1() {
  String s1 = "abc";//s1直接指向常量池中的"abc"
  String s2 = "a" + "bc";//s2后面的字符串值可以在编译期就确定下来,所以s2直接指向常量池里的"abc"  
  System.out.println(s1);
  System.out.println(s2);
  System.out.println(s1.equals(s2));                     
  System.out.println(s1 == s2);  // 因此这里的结果为 true true
}
private static void demo2() {
  String s1 = "abc";//s1直接指向常量池中的"abc"
  String s2 = "a";
  String s3 = "bc";
  String s4 = s2 + s3; //s4后面的字符串值不能在编译期就确定下来,所以不能指向常量池中的字符串
   //因此s1和s4指向的不是同一个值 故为false
   
System.out.println(s1);
  System.out.println(s4);
  System.out.println(s1.equals(s4));
  System.out.println(s1 == s4);
}                                 //而这个就是true flase

==两边为引用变量时比较两边的变量是否同时指向同一个引用对象 是 返回true 不是 返回false
equals 方法是判断两个对象的值是否相等,s1和s4里存储的都是对象的地址 他们指向不一样 所以返回false


一般情况下 比较的都是引用变量的情况下 equals和==的作用是一样的 只不过 equals方法可以被复写,如果没有
被复写 他们两个的作用就是一样的。

评分

参与人数 1技术分 +1 收起 理由
田建 + 1 赞一个!

查看全部评分

回复 使用道具 举报
值类型是存储在内存中的堆栈(栈),而引用类型的变量在栈中仅仅是存储引用类型的变量的地址
,而其本身这存储在堆中。
==操作比较的是两个变量的值是否相等,对引用类型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
equals操作表示两个变量是否是对同一个对象的引用,即堆中的内容是否相同。


回复 使用道具 举报
3楼正解,我再补充一点
   String 对象(内存)的不变性机制会使修改String字符串时,产生大量的对象,因为每次改变字符串,都会生成一个新的String。
java 为了更有效的使用内存,常量池在编译期遇见String 字符串时,它会检查该池内是否已经存在相同的String 字符串
如果找到,就把新变量的引用指向现有的字符串对象,不创建任何新的String 常量对象没找到再创建新的。
      所以楼主问题中的第一部分 是true true 因为编译期间 发现常量池内已经存在该对象了,所以两个引用指向同一个对象。
   而第二部分中,s4 涉及到s2和s3两个对象,需要编译后 加载.class文件 建立对象之后才能确定
所以没指向常量池中的对象,而是新建了一个,由于指向不同的对象,所以为false。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马