本帖最后由 xiaolinyouni 于 2011-06-18 08:44:15 编辑

解决方案 »

  1.   

    如果你看得懂javap命令的结果就一切都明白了javap -c equalsTest
      

  2.   


    前天刚开始看java,虽然以前学c,但是我表示不懂...
      

  3.   

    equals就是值的比较
    ==就是对象引用的比较
      

  4.   

    http://blog.csdn.net/DryKillLogic/archive/2011/03/04/6223964.aspx你看看这个链接。
      

  5.   

    你大约是奇怪为什么s3==s4吧s3 = "abc"; 
    创建一个"abc"字符串并放置在常量池中,把s3指向它s4 = "abc";
    因为常量池中已经有"abc"了,就不创建了,把s4指向它s3==s4? 返回true"abc"=="abc"?
    过程跟以上一样
      

  6.   

    "abc"是否会被回收? 请高手明确的回答一下 = =
      

  7.   

    public class equalsTest
    {
        public static void main(String args[])
        {
            A obj1=new A();
            A obj2=new A();
            String s1,s2,s3="abc",s4="abc";
            s1=new String("abc");
            s2=new String("abc");
            System.out.println("s1=s2?  "+(s1.equals(s2))); // String.equals(String) 为比较两个字符串的值,显然s1、s2的值一样,所以输出true
            System.out.println("s1=s3?  "+(s1==s3)); // ==为对象的比较,s1为new出的一个对象,s3为指向"abc"的对象,两者不一样,输出false
            System.out.println("s1=s3?  "+(s1.equals(s3))); // 比较字符串的值,输出true
            System.out.println("s3=s4?  "+(s3==s4)); // s3、s4都指向"abc",所以输出true
            System.out.println("s2=s3?  "+(s2.equals(s3))); // 比较字符串的值,输出true
            System.out.println("obj1=obj2?  "+(obj1.equals(obj2))); // 两个不同的对象,在没有重写equals方法时,equals方法就是==,也即判断两个对象是否是同一个对象,所以输出false
            System.out.println("s1=s2?  "+(s1==s2)); // 比较两个不同的对象,输出false
            obj1=obj2;
            System.out.println("obj1=obj2?在obj2赋值给obj1之后  "+(obj1.equals(obj2))); // 此时,obj1指向obj2指向的对象,即两者都指向第二个A类的对象,返回true
            System.out.println("obj1=obj2?在obj2赋值给obj1之后  "+(obj1==obj2)); // 同上
        }
    }
      

  8.   

    这个问题,首先LZ要先弄清楚对象和变量String s = "abc";
    s是个变量,"abc"是个对象,s和"abc"是什么关系呢?那就是s引用"abc"对象,也就是s的值是"abc"对象的地址
    变量本身有自己的地址,变量的地址保存的内容,就是变量的值
    所以,String s = "abc",也就是在s变量的地址里保存"abc"的地址再来讨论基本类型和引用类型的区别
    int i = 5; int是基本类型,为何说是基本类型呢,首先上面说了,i是个变量,i本身有个地址,那么i地址里保存的是什么呢?就是5,内存是二进制的形式,保存的是00000000000000000000000000000101,int是4个字节32位,也就是说基本类型的变量的地址里保存的就是我们文面上看到的信息,上面说了,变量的值就是变量本身的地址里保存的内容,所以我们一眼就知道i的值是5,即i和5之间是直接对应的关系,我们把这样的类型叫做基本类型String s = "abc"; String是对象类型,上面说了,s的地址里保存的是"abc"对象的地址,假设"abc"对象的地址是0xABCD,对象类型的变量本身也是4个字节32位,
    那么s的内存保存的就是00000000000000001010101111001101,可以看到"abc"这样的内容并没有被直接保存在s的内存里,s的内存保存的时"abc"的地址0xABCD,也就是"abc"这样的字符串信息是保存在另外一个地址里,这个地址就是0xABCD,所以对象类型的变量的地址里保存的信息不是我们文面上看到的信息,也就是说s的内存地址不直接保存"abc"这样的信息,即s和"abc"不是直接对应的关系,中间加了一个对象的地址,也就是要查看s所引用的对象的值,就用先在s的内存里拿到一个地址,然后再去这个地址里把需要的信息取出来。这样的类型,我们叫做引用类型。所以我们把String s= "abc",也称为s引用"abc",并不是s的值是"abc"好,这下可以来讨论==和equals的问题了
    ==是比较两个变量的值,equals是比较两个对象的值
    String s1 = "abc";
    String s2 = "abc";
    s1==s2结果是true
    首先,变量s1的值就是变量s1的地址里保存的内容,它的内容就是"abc"对象的地址
    同样的,变量s2的值就是变量s2的地址里保存的内容,它的内容也是"abc"对象的地址
    所以s1==s2,两个变量的值相等
    对于基本类型就更好理解了
    int i1 = 5;
    int i2 = 5;
    i1==i2结果是true,因为i1的地址里保存的是5,i2的地址里保存的也是5,也就是i1和i2的值相同再看
    String s1 = "abc";
    String s2 = new String("abc");
    s1的地址里保存的是"abc"对象的地址(这个地址在常量池里的一个地址),s2的地址里保存的是new String("abc")这个对象的地址(这个地址是堆中的地址),很显然,"abc"对象的地址和new String("abc")对象的地址不相同,所以s1的值和s2的值也不相同,所以s1==s2的结果是false
    根据上面分析我们知道,"abc"对象的地址里保存的信息是"abc"字符串,同样的,new String("abc")的地址里保存的也是"abc"字符串,我们知道这两个字符串的内容是一样的,当我们去比较s1和s2是,我们比不想比较s1和s2的值,而是想比较它们所引用的对象的值,那么用==是不行的,该怎么办呢?于是就出现了equals.
    equals比较的不是变量s1和s2的值,而是它们所引用的对象的值,也就是说,equals是先从s1的地址里拿到"abc"对象的地址,然后再到该地址里取出"abc"这样的字符串信息,接着从s2的地址里拿到new String("abc")对象的地址,然后再到该地址取出"abc"这样的字符串信息,然后比较取出的这两个字符串的内容是否相同,相同则返回true,不相同则返回false,显然,取出的这两个字符串的内容都是"abc",是相同的,所以s1.equals(s2)为true所以,==是直接比较两个变量的值(也就是直接比较两个变量的内存的信息),equals是比较两个变量所引用的对象的值(也就是先从变量的内存拿到一个对象的地址,再到该对象的地址里取出信息来比较)
      

  9.   

    6>>   obj1=obj2?  false                           //equals
    这里漏说了一点,equals是个方法,可以重写,上面的equals分析是针对于String重写的equals分析的,Object的equals方法是直接返回 o1==o2,也就是说直接比较两个变量的值,String重写了该方法,也就是我上面分析的比较的过程
      

  10.   

    常量池  和  堆 有什么区别...常量池不是在堆里面么?
    还有就是int i1=5;和int i2=5;的比较我还是不明白...
      

  11.   


    6L给的网址:http://blog.csdn.net/DryKillLogic/archive/2011/03/04/6223964.aspx 你没看?常量池不在堆中吧可以理解它为一张表当程序中出现类似"abc"的常量字符串时,首先查找常量池中是否存在"abc",如果没有,则在堆中建立一个"abc"的对象;如果有则返回堆中对象的地址,我的理解。
      

  12.   


    常量池是在方法区,方法区也是在堆内存分配的
    即使同在堆中,也是不同的两个内存区域

    String s1 = new String("abc");
    String s2 = new String("abc");
    两个new String("abc")分配的是不同的内存,否则就不相干扰了。new这个操作符是申请内存,然后在这块内存里填充信息。所以String s1 = new String("abc");的时候,先申请一块内存,在里面填充一些相关的信息,然后String s2 = new String("abc");的时候,再申请一块内存,在里面填充一一些相关信息,这两块内存是不一样的。
    打个比方,我们把内存分配看作盒子加工厂分配盒子,盒子加工厂把可用的盒子放在了仓库的架子里,我们把这个架子叫做堆,那么第一次new String("abc")的时候,我们向盒子加工厂申请一个盒子,假设我们得到的是架子第一层的第一个盒子,我们假设它的编号001,然后在这个盒子放上一些相关的信息,如"abc"字符串,第二次new String("abc")的时候,我们再申请一个盒子,假设我们得到的是架子的第二层的第二个盒子,我们假设它的编号是102,然后在放上一些相关的信息,如"abc"字符串,显然,这是两个不同的盒子,但我们可以在盒子里放相同的东西"abc"字符串。这里,我们把001盒子和它所装的"abc"看作一个整体,统称为对象,同样的102盒子和它所装的"abc"也叫做一个对象,001和102就分别是这两个对象的地址,"abc"就是这两个对象的内容。
    好了,那么对于String s1 = new String("abc");我们看还差个什么?还差个s1,上面的说了,s1是个变量,变量本身有自己的内存空间,也就是说s1也是个盒子,同样的s2也有个盒子,s1和s2这两个盒子是加工厂临时使用的盒子,也就是s1和s2是在方法栈里被指令操作的临时变量,和架子上的盒子是不同的,那么String s1 = new String("abc");的时候,加工厂在方法栈的s1这个盒子做了什么事情呢?加工厂做的事情就是,在s1盒子里放上001,这里的001就是我们上面说的第一个new String("abc")的盒子编号,也就是对象的地址,同样的,String s2 = new String("abc"),就相当于加工厂在s2盒子里放上102,上面说了,==是判断两个变量的值,也就是两个变量的内存里保存的内容,那么==就相当于判断s1盒子和s2盒子里的东西,显然,放的是两个不同的编号,是不一样的,所以s1==s2为false,而equals是比较两个变量所引用的对象的值,也就是说,先从s1盒子里拿到一个001的编号,然后找到001编号的盒子,从里面取出"abc"字符串,接着从s2盒子里拿到一个102编号,然后找到102编号的盒子,从里面取出"abc"字符串,然后把取得的这两个字符串进行比较,显然这两个字符串的内容都是"abc",所以相同,所以s1.equasl(s2)为true对于基本类型的比较,
    首先还是上面的比方,int i1 = 5;那么加工厂会在临时使用的盒子i1里放上一个5,同样的int i2 = 5,加工厂会在临时使用的i2盒子里也放上一个5,==比较就是比较i1和i2盒子里所装的东西,很显然,都是5,所以相同,所以i1==i2通过这个比方也可以知道,基本类型的变量,保存的就是文面上信息,即i1和i2盒子里直接保存5,而引用类型的变量,保存的是对象的地址,因为首先要向加工厂申请从架子里获得一个盒子,然后把盒子的编号保存(也就是首先会在堆内存分配空间得到一个对象的内存地址,然后再把这个内存的地址保存到引用变量本身的内存里)
      

  13.   

    == 判断两边的东东是不是“同一”
    equals 判断两边的东东是不是内容一样所以 如果"==",则一定"equals"
      

  14.   

    从早上来发帖到现在一天,有空就看这个问题,在各位网友的帮助下终于算是明白许多了!!!结贴!
    6楼的帖子的那个链接很好,虽然没看懂但是说明白了class文件中那些乱七八槽的东西,等我以后再看,现在实在理解不能!+20
    7楼,只是多了一个芝麻点,但很正确.+10
    10楼,是通过对象不同的分析给我解释的(但是我觉得这种解释很勉强,也只能说是你自己的理解吧)++20
    11楼,写的很好,很清晰,也很准确.+45