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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© FFF 金牌黑马   /  2013-10-3 11:12  /  2585 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 FFF 于 2013-10-3 13:41 编辑

  1. public class temp10_03 {

  2. public static void main(String[] args){
  3. String s0 = "kvill";
  4. String s1 = "kvill";
  5. String s2 = "kv"+"ill";

  6. int i0 = 01 ;
  7. int i1 = 01 ;
  8. int i2 = 0+1;

  9. System.out.println( s0 == s1 );
  10. System.out.println( s0 == s2 );

  11. System.out.println( i0 == i1 );
  12. System.out.println( i0 == i2 );
  13. }
  14. }
复制代码
为什么输出结果都是True呢?不是说比较的时候是比较两个变量的内存地址吗?为什么都是一样的?

评分

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

查看全部评分

11 个回复

倒序浏览
本帖最后由 Simple_love 于 2013-10-3 11:31 编辑

你之所以为true, 是因为s1 s2 类类型的变量指向了同一个对象"kvill", i0、i1同样也是类类型的变量指定了同一个对象01, 由于双等号是比较对象是否相同, 所有运行的结果都为true

评分

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

查看全部评分

回复 使用道具 举报
String s0 = "kvill"时, 栈内存的变量s0指向了常量池中的“kvill”(常量池没有kvill的话就会被创建),String s1 = "kvill"时,s1和s0指向的都是常量池的“kvill”,String s2 = "kv"+"ill"时,创建了三个对象,“kv”和“ill“,但是没有创建”kvill“,因为之前已经创建了,它们都是同一份的”kvill“,所以s2指向的也是s0和s1一样的地址。下面int类型的比较,道理同String类型的比较,不过它们是储存在栈内存中,同样是栈内存中已经有了的话,就不会再开辟新的内存空间。希望能帮到你。

评分

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

查看全部评分

回复 使用道具 举报
关于字符串的创建有两种方式,
1.String s = "abc";//这个用双引号引起来的直接会将abc放入常量池中,如果你在写一个String s1 = "abc";则s2会直接指向常量池中的abc,不会在新创建一个
2.String s2= new String("abc");//这个则是创建了两个对象,一个是new出来的,在堆中,一个是在常量池中
如果你这样比较
  1. public class temp10_03 {

  2. public static void main(String[] args){
  3. String s0 = new String("kivll");
  4. String s1 = new String("kvill");
  5. String s2 = "kv"+"ill";

  6. int i0 = 01 ;
  7. int i1 = 01 ;
  8. int i2 = 0+1;

  9. System.out.println( s0 == s1 );
  10. System.out.println( s0 == s2 );

  11. System.out.println( i0 == i1 );
  12. System.out.println( i0 == i2 );
  13. }
  14. }
复制代码
肯定是false

int i0 = 01 ;
int i1 = 01 ;
int i2 = 0+1;//你这是在比较01是不是等于01,也是true,这个没比较对象

评分

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

查看全部评分

回复 使用道具 举报
陈钦涛 发表于 2013-10-3 11:34
String s0 = "kvill"时, 栈内存的变量s0指向了常量池中的“kvill”(常量池没有kvill的话就会被创建),Stri ...

int类型是基本数据类型,String是一直特殊的引用数据类型,我认为他俩应该不太一样吧,
回复 使用道具 举报
关于==,再给你举个例子:因为一般==会和equals来比较。
Integer i1=new Integer(2);
Integer i2=new Integer(2);
i1==i2      这就是false
i1.equals(i2)   这是true;
-----------------------------------------------------------------------
总结,你可以不去理会到底有没有在堆内存中有没有开辟新空间,可以这样理解:
    如果比的是变量,那只能用==,不能用equals    ,这时==比的是堆内存中的值。因为在堆内存中,值一样确实是不开辟新空间,所以地址也是一样的。
    如果比的是对象,那==比的时,比的是地址。 用equals比的则是值,理由同上。
而你举的例子全是变量,比的是堆内存中的指向的值。

评分

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

查看全部评分

回复 使用道具 举报
←佐手邊の永远 发表于 2013-10-3 11:43
int类型是基本数据类型,String是一直特殊的引用数据类型,我认为他俩应该不太一样吧, ...

我说的是基本数据类型在栈内存和引用数据类型在栈内存和常量池的创建方式类似,当然==比较基本数据类型的时候是比较它们的值,引用数据类型比较的是它们的内存地址。
回复 使用道具 举报
String s2= new String("abc");创建了3个,栈 堆 常量池
回复 使用道具 举报
陈钦涛 发表于 2013-10-3 11:54
我说的是基本数据类型在栈内存和引用数据类型在栈内存和常量池的创建方式类似,当然==比较基本数据类型的 ...

懂了。。。。。。{:soso_e100:}
回复 使用道具 举报

                String s0 = "kvill";
                String s1 = "kvill";
                String s2 = "kv" + "ill";

                int i0 = 01;
                int i1 = 01;
                int i2 = 0 + 1;

                System.out.println(s0 == s1);  //String因为是引用类型,这类变量声明时不会分配内存,只是存储了一个内存地址,想具体知道看看数据结构就好了。s0的引用地址是"kvill",s1的引用地址也是"kvill",包括s2也是相同的引用地址所以是true
                System.out.println(s0 == s2);

                System.out.println(i0 == i1);//你的数字值都是1 肯定是等于的
                System.out.println(i0 == i2);

评分

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

查看全部评分

回复 使用道具 举报
{:soso_e110:}
回复 使用道具 举报
本帖最后由 麦子 于 2013-10-3 19:14 编辑

哥么,给你说个大白话吧
String s0 = new String("kivll");
String s1 = new String("kvill");
String s2 = "kv"+"ill";
s0==s1这个为true不用我讲吧,为什么s0==s2也为true,那是因为它先完成了你的字符串相加才赋的值
,那s2肯定也是kvill啊!
我大概知道你想说的是什么
String s2 = "kv";
String s3 = "ill";
String s4 = s2+s3;
System.out.println( s0 == s1 );
System.out.println( s0 == s4 );
此时,s4在堆内存中的只和s2就不一样了
以上代码就是你要的结果了
要想比较字符串的内容,应该使用该对象的方法equals();
int i0 = 01 ;
int i1 = 01 ;
int i2 = 0+1;
至于以上代码,因为都是简单的基本数据类型,比较的就是它的值


评分

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

查看全部评分

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