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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马张扬 中级黑马   /  2012-5-28 00:26  /  3386 人查看  /  12 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

class  StringDemo
{
        public static void main(String[] args)
        {
                String x = "a";
                String y = "a";
                String m = new String("a");
                String n = new String("a");

                System.out.println(x==y);
                System.out.println(m==n);

        }
}


结果一个true 一个false  这是个什么原因!

12 个回复

倒序浏览
1、字符串对象的创建:String x = "a"。
    由于字符串对象的大量使用,Java中为了节省内存空间和运行时间,在编译阶段就把所有的字符串文字放到一个文字池中,而运行时文字池成为常量池的一部分。文字池的好处是该池中    所有相同的字符串常量被合并,只占用一个空间。
    对两个引用变量,使用“==”判断它们的值是否相等,即是否指向同一个对象。
        String x = "a";
             String y = "a";
             System.out.println(x==y); //输出必然为TRUE
       输出显示为TURE是因为,两个字符串文字保存为一个对象。
    就是说,上面的代码只在文件池pool中创建了一个String 对象。
2、字符串对象的创建:String m = new String("a")
       这里“a”本身就是文件池pool中的一个对象,而在运行时执行new String()时,将文件池pool中的对象复制一份到堆heap中,并把heap中的这个对象的引用交给s持有。  
     String m = new String("a")这条语句就创建了2个String对象。
         String m = new String("a");
              String n = new String("a");
             System.out.println(m==n);
       这时候用”==“判断就可知,虽然两个对象的”内容“相同,但两个引用变量所持有的引用不同。
    上面的代码创建了3个字符串对象String Object,文件池pool中一个存有字符串”a“,heap中两个m和n。

回复 使用道具 举报
x在常量池中创建"a",y创建时先在常量池中寻找,看有没需要的字符串,y也指向"a",所以x和y是相等的,返回true。而m和n是分别创建一个字符串存放在堆内存中,所存储的内存地址不同,所以,m和n相比返回false。
回复 使用道具 举报
                String x = "a";
                String y = "a";
                String m = new String("a");
                String n = new String("a");

                System.out.println(x==y);
                System.out.println(m==n);

首先"=="和equals()方法不同的是,"=="是用来比较两个的地址值是否相同的,而equals()是用来比较两个对象的内容是否相同的,
明显, String m = new String("a");和  String n = new String("a");是两个对象了,所以返回的false,如果用equals()那就是true。
而x = "a";y = "a";指向的都是同一个对象那就是"a"因为字符串池中只有一个"a"字符串所以是true。



回复 使用道具 举报
x和y指向的都是“a”,m和n虽然输出为“a“,但指向的是两个不同的String对象。
回复 使用道具 举报
本帖最后由 曹俊 于 2012-5-28 01:15 编辑


哥们,这是我对你的代码在内存中所画的图:
首先你定义了两个字符串的变量,分别是String x = "a"和String y = "b";  它们在栈内存的分配位置如图。
接着你又创建了两个新的对象,分别是String m = new String("a")和String n = new String("a");这里的String只是相当于类名,我估计你混淆了这的String是字符串。
图中你也看到了,新建的对象它的分配位置在堆内存中,是两个不同的对象,地址位置不同,所以当你在打印输出语句的时候,x,y两个变量的值是相同的,所以x==y的值返回的事true,但两个新建的对象由于地址位置不一样(地址位置就是我写的0x0023和0x0045,这两个十六进制的数是瞎写的,具体请看毕老师的关于内存图你就知道了),所以它们是不相等的,所以返回的值是false。
希望你能明白...
回复 使用道具 举报
本帖最后由 袁錦泰 于 2012-5-28 01:41 编辑

举一反三,根据不同情况为你解释其比较方式的不同,具体如下:
|--对于基本数据类型
    |--只有"==",没有equals()方法,比较两者内容是否相等
|--对于字符串
    |--String类不是基本数据类型
    |--"=="比较两者内存地址是否相等,equals()方法是重写了Object类中的equals()方法,比较两者内容是否相等.
    |--字符串被存储在方法区内的常量池中,只要值相等其指的都是同一个内存地址,"=="和equals()方法的结果无区别(源代码中有所体现)
|--对于对象实例
    |--"=="比较两者内存地址是否相等,equals()方法是重写了Object类中的equals()方法,比较两者内存地址是否相等,但通常我们会自己重写equals()方法,将其改变为比较两者内容是否相等
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
总结:具体"=="与equals()方法所比较的是什么并非固定,而是根据不同情况进行区分的,千万不要一概而论!!!
回复 使用道具 举报
String x = "a";           //x指向了"a"
String y = "a";          //y也指向了"a"   x y 指向同一块内存地址相=

String m = new String("a");
String n = new String("a");  //x y分别new了一块内存地址不=
System.out.println(x==y);
System.out.println(m==n);

回复 使用道具 举报
本帖最后由 胡团乐 于 2012-5-28 07:07 编辑

String x = "a";           //x指向了"a"
String y = "a";          //y也指向了"a"   x y 指向同一块内存地址相=

String m = new String("a");
String n = new String("a");  //x y分别new了一块内存地址不=
System.out.println(x==y);
System.out.println(m==n);
发了两遍不好意思  网络延迟
回复 使用道具 举报
徐炯 中级黑马 2012-5-28 08:35:52
9#
袁錦泰 发表于 2012-5-28 01:38
举一反三,根据不同情况为你解释其比较方式的不同,具体如下:
|--对于基本数据类型
    |--只有"==",没有equa ...

回答的真好,赞一个!
回复 使用道具 举报
徐炯 发表于 2012-5-28 08:35
回答的真好,赞一个!

哪裡哪裡,不要客氣,以後彼此多交流. 大家好才是真的好...
回复 使用道具 举报
jxj4227982333 发表于 2012-5-28 00:58
String x = "a";
                String y = "a";
                String m = new Strin ...

昨天刚刚看到equals() ,对象的概念还是不懂
回复 使用道具 举报
String x = "a";
String y = "a";
创建的对象是在字符串常量池中,常量池中若字符串已有了,就不会再创建新的字符串  
String m = new String("a");
String n = new String("a");  
通过new关键字在堆内存中,开辟了2个不同的对象,不同的内存空间,不同的地址
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马