public static  void main(String[] args){
        String a=new String("aa");
        String b=new String("aa");
        Person p1=new Person("aa",12);
        Person p2=new Person("aa",12);
        System.out.println(a.equals(b));
        System.out.println(p1.equals(p2));
    }为什么第一个结果是true,而第二个是false呢,求大神指点

解决方案 »

  1.   

    第一个比较字符串内容,相同所以true。第二个要看person是如何实现equals的。看他比较的什么
      

  2.   

    一般来说为了比较两个变量是否相等的话,基本类型的变量用“==”号。
    而引用类型的变量就不能用这个了。当比较引用类型变量时,你用==的话,比较的是两个变量是不是同一个对象,如果是同一个对象,则返回true,否则返回false。
    比如你的代码:
    Person p1=new Person("aa",12);
    Person p2=new Person("aa",12);
    p1和p2的成员变量一样,但是是两个不同的对象,所以p1==p2返回的就是false。
    而equals()是一个方法,是object类的方法。默认的效果和==是一样的,只有两个变量指向同一个对象时,才返回true。
    所以你直接使用 System.out.println(p1.equals(p2));,输出的是false。
    而String类(字符串)重写了equlas()方法(希望你学到了继承方面的知识)。
    但是你的Person类应该没有重写这个方法,直接是默认的,肯定返回的是默认的!
      

  3.   

    在object类中引用数据类型==和equals比较的都是内存地址吗,new了两个String对象不就应该有两个地址吗,为什么还是true
      

  4.   

    这就个Java多态的表现了,第一个的equal是调用的是String的equal,而第二个equal调用的是Object的equal,当然不一样,直接给你看源代码吧。Object的equal
       public boolean equals(Object obj) {
            return (this == obj);
        }
    String的equal
      
        public boolean equals(Object anObject) {
            if (this == anObject) {
                return true;
            }
            if (anObject instanceof String) {
                String anotherString = (String)anObject;
                int n = value.length;
                if (n == anotherString.value.length) {
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
                    while (n-- != 0) {
                        if (v1[i] != v2[i])
                            return false;
                        i++;
                    }
                    return true;
                }
            }
            return false;
        }
      

  5.   

    ==比较的是内存中的存储的东西
       对于基本类型来说,内存中存储的是实际数值
       对于引用类型来说,内存中存诸的是对象的地址(每new一次新的对象,就会在新的地址存储这个对象)equals是按equals方法来比较的,如果没有重写equals方法,则参照父类的equals方法
    对于String对象也适用于上述规则,但要注意String有个常量池,有时候会重用常量池的对象,以至于某些情况下==会返回true
    参照这个问题中我的回答:
    https://bbs.csdn.net/topics/392391937   
      

  6.   

    第一个比较的字符,两个值一样就是true,第二个你是在比较内存地址,你创建两两个不同的内存地址,所以为false
      

  7.   

    得分清基本数据类型,和引用数据类型 ,基本数据类型都是用==记性计较  ,而引用数据类型要比较地址值是否相同.所以要用.equals进行比较 . 
      

  8.   

    因为Java中String类,重写了equals()方法,令其比较对象的值。因为a和b的值相同都是“aa”,故a.equals(b) = true。而“==” 比较的是对象引用,a,b是两个不同对象,所以 a == b是会返回false 的。
    而Person类应该是你自定义的类,如果自定义类中没有重写equals()方法,默认调用equals()方法,比较的是对象引用,这个时候,equals()方法和“==”功能一样。
    明显,p1,p2是两个不同的对象,所以,p1.equals(p2) = false。这里,p1 == p2也是返回false。
      

  9.   

    person是如何实现equals的?如果没有实现 就和==一样 只有是同一个对象才会返回true
      

  10.   

    Person没有重写equals方法
      

  11.   

    楼主,在object类中引用数据类型==和equals确实比较的都是内存地址。而像String,Integer等引用数据类型因为重写了equals方法,所以equals比较的是内容,==比较的是地址。
      

  12.   

    另外,8中基础数据类型==比较的是内容。注意这个:
    https://img-blog.csdn.net/20180504150042541?water/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xlZ2VuZGFyeWhhaGE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70
    第一个输出了true,第二个输出false,我们都知道引用数据类型时“==”比较对象时比较的不是内容而是引用,但因为在java中早就封装好-128到127之间的数字了,所以当数字介于它们之间时,就不会new新的对象了,而是之间引用常量池中的Integer对象。
      

  13.   

    我也是初学者,我是这么理解的。equals比较的是属性,==比较的是是否相同。
    第一个可以认为是在内存中指向同一个内存空间。如  你上面的第一个;
    第二个可以这么认为 一个张三  一个李四   他们都是12岁 。他们是同一个人吗。你觉得。
      

  14.   

    看楼主的问题,是应该知道至少在字符串比较的时候,应该用 equals  而不是用 ==
    == 操作符比较的是两个对象是否相同,而equals其实是一个方法,比较内容是否一样为什么楼主的代码结果会那样,因为:
    1、equals 方法其实是在 Object 类中定义的,它有一个默认的实现,只是简单点进行 == 比较:public boolean equals(Object obj) {
        return (this == obj);
    }
    2、而 String 类重写了 equals 方法,这个就有点长了:
    public boolean equals(Object anObject) {
    if (this == anObject) {
    return true;
    }
    if (anObject instanceof String) {
    String anotherString = (String) anObject;
    int n = value.length;
    if (n == anotherString.value.length) {
    char v1[] = value;
    char v2[] = anotherString.value;
    int i = 0;
    while (n-- != 0) {
    if (v1[i] != v2[i])
    return false;
    i++;
    }
    return true;
    }
    }
    return false;
    }
      

  15.   

    所以,楼主的 Pserson 类也想达到你希望的效果,可以给 Person 类重写一个 equals 方法:
    @Override
    public boolean equals(Object other){
    if(other == null)
    return false;
    if(other instanceof Person){
    Person p1 = (Person)other;
    if(this.name != null){
        if(this.name.equals(p2.name) == false) return false;
    }else {
    if(p1.name != null) return false;
    }
    ......
    }else{
    return false;
    }
    }
      

  16.   

    第一个比较字符串内容,相同所以true。第二个要看person是如何实现equals的。应该用 equals  而不是用 ==
    == 操作符比较的是两个对象是否相同,而equals其实是一个方法,比较内容是否一样
      

  17.   

    一开始我也不太理解 == 和 equals 的区别,问百度问google得出的结论其实都差不多无非就是 是不是引用同一个对象的问题,总归理解的不是很深为什么因为不知道代码是怎么运行的,所以我建议楼主用Debug模式一步一步跟下去,多跟几次就能理解 == 和 equals的区别了.编程这种东西还是要自己动手看别人的总归只是看看没有自己东西来的快.
      

  18.   

     String a=new String("aa");
            String b=new String("aa");
    同学你好,这是堆栈之间的动态分配,我看能不能画图给你
    首先string类型是一个引用数据类型,一旦声明,就在栈里有个引用类型的a,如果new出来一个实例化对象,堆里面就会自动分配一个内存空间用于存放字符串"aa".   于是引用类型的a就指向堆里面的字符串"aa".  (下面的字符型b也这样理解)。
    equals本身比较 就是java中的一个方法,它先比较地址再比较内容,而"等于"在字符型比较的是地址 地址一样则直接返回true,不一样再比较字符串内容 一样返回true。
    由此可得:   你这两行代码内容就是在堆里开辟了两个内容空间且对应在栈里的地址也不一样,
    但是你使用的是equals比较    可见在堆里的内存空间里的内容相等所以结果是-----------true。
      

  19.   

    equals是要重写的,如果不重写与==没有区别,这是equals的实现
      

  20.   

    第一个比较的是两个字符串,第二个比较的是两个对象!第二个其实是比较的两个对象地址,因为地址不一样所以是false
    ,equals是两个字符串之间的比较,所以第一个是true
      

  21.   

    看了几个回答,好几个说具体看person里面的equals是怎么实现的? 
    我猜想,如果楼主知道是怎么实现的,就不来这里问了。下面是具体解释:
    第一个是字符串的比较,在jdk源码中重写了equals方法,
    比较的是两个字符串是否一样,所以返回true。
    =====具体为什么会是一样的字符串,涉及到JVM对字符串的处理。有兴趣可以看一下。第二个是Person的比较,因为没有在person里面更改equals方法,
    默认比较的是地址,两个新生成的对象物理地址肯定不一样,所以为false。
    =====楼主可以直接System.out.println(p1);System.out.println(p2);这两个是不一样的哦~如果还是不理解,可以这么理解:
            String a=new String("张伟");
            String b=new String("张伟");
            Person p1=new Person("张伟",12);
            Person p2=new Person("张伟",12);
    中国叫张伟的人那么多,名字都是一样的~~
    p1和p2虽然名字都是叫张伟,但是肯定不是一个人啊,对不对?
      

  22.   

    看你的person类有没有重写equals方法,若没有,调用equals就是 == 比较两个对象的地址
      

  23.   

    简单数据类型直接比较字符串,你自定义的person类型是比较的存储地址,当然会false.
      

  24.   

    这个只要好好看看java的栈和堆就可以了,明白什么类型变量在栈里,什么在堆里 就会明白了
      

  25.   

    equals比较的的内容,而==比较的是内存地址
      

  26.   

    equals比较的是具体的值,都是“aa”所以结果是true
    但是你用这个来比较对象的时候,需要对方法进行重写
    ==是用来比较地址的
      

  27.   

    因为String类重写了equals()方法,它比较的是对象的内容,a和b对象的内容都是"aa",所以结果为true;而您自己定义的Person类显然没有重写过equals()方法,它默认是比较两个对象的引用(地址)是否相同,p1和p2是两个不同的对象,所以结果是false。希望采纳,谢谢。
      

  28.   

    一、String 和 Person 一个是自定义对象,String 底层重写了equals()方法,而自定义对象没有重写equals方法,比较的还是地址等不等;
      

  29.   

    equals()在Object类里面定义的,如果两个变量指向同一个对象,则返回true,否则返回false,因为Object类是所有类的超类,String类重写了Object类的equals()方法,只要两个字符串的字符序列完全相同,就返回true,所有第一个的两个字符串的字符序列完全相同,返回true,第二个类没有重写equals()方法,调用的equals(0方法依然是从超类Object那里继承到的方法,因为使用new关键字定义的了两个对象,所以使用equals()方法返回的是false.
      

  30.   

    第一个String已经重写了hashcode和equals方法,所以实际比较的是,所以返回true。
    而第二个person对象,你如果没有重写hashCode和equals方法,默认比较的地址,而new person对象的地址是不同的,所以返回false,
      

  31.   

    看java api中的object的equals()的说明:只有a,b指向同一个对象的时候才返回true      望采纳。 
    equalspublic boolean equals(Object obj)    指示其他某个对象是否与此对象“相等”。    equals 方法在非空对象引用上实现相等关系:        自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
            对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
            传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
            一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
            对于任何非空引用值 x,x.equals(null) 都应返回 false。    Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。    注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。    参数:
            obj - 要与之比较的引用对象。 
        返回:
            如果此对象与 obj 参数相同,则返回 true;否则返回 false。 
      还有String 类的api的equals 方法:只要他们的值相同就返回true   望采纳
     equalspublic boolean equals(Object anObject)    将此字符串与指定的对象比较。当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。    覆盖:
            类 Object 中的 equals     参数:
            anObject - 与此 String 进行比较的对象。 
        返回:
            如果给定对象表示的 String 与此 String 相等,则返回 true;否则返回 false。 
        另请参见:
            compareTo(String), equalsIgnoreCase(String) 
      

  32.   


    这2个String里的字符串相同 应该是都在字符串常量池里吧。。直接在双引号里的 才在字符串常量池
      

  33.   


    额 我看错了。。我看成String str=“aa”了 没注意,他是new了一下
      

  34.   

    你得看下String的源码,这个重写了equal的方法。而我们自己定义的,如果没有重新equals的方法,是不能简单的比较的。
    java对象实际上和C或C++的指针类似,都是属于引用类型。
    另外,所说的==和equals是不一样的。equals往往比较的是字符串的值是否相等,而==比较的是值的大小(注意,是值,如果是java对象比较,那么就是java对象的地址所在值,你有空看下jvm的相关知识,就清楚java的存储方式了。)
      

  35.   

    public static  void main(String[] args){
            String a=new String("aa");
            String b=new String("aa");
            Person p1=new Person("aa",12);
            Person p2=new Person("aa",12);
            System.out.println(a.equals(b));
            System.out.println(p1.equals(p2));
        }第一个结果是true,是因为 String 类 重写了Object类的 equals()方法 比较的是两个对象的内容是否相同 
    而第二个是false  是因为Person类创建的时候没有重写Object类的equals()方法  在底层中还是用==来比较两个地址引用是否相等  由于new了两个对象,所以他们的地址肯定是不相等的。 
      

  36.   

    你可以去了解一下类加载的时候对常量的处理,你那两句new String的代码中“abc”是常量,内存中有常量池,单独存放代码中出现的常量,你就算写了很多句String s = new String("abc"),常量池里也只有一个“abc”,他是把常量池中“abc”的地址赋值给变量s,所以,你那s1,s2,s3...s100的地址都是一样的,都指向常量池中的“abc”,所以是true
      

  37.   

    person自定义类没重写equals方法
      

  38.   

    https://blog.csdn.net/v2020877/article/details/82056441
      

  39.   

    ==比较的是首地址 即指向保存这个数据的内存空间
    equals 不重写的话也是比较首地址 
    因为String 等java提供的类都重写了equals方法 所以他们比较的是内容是否相同
      

  40.   

    基本类型==比较的是你看到的那个值,引用类型是他们在计算机中存放的地址。
    引用类型equals比较也是他们在计算机中的地址,但当你比较的是对象时,你
    必须重写equals,不然比较的就是对象中第一个属性在计算机中存放的地址。
    String比较特殊,它的equals比较的是你看到的值,因为它已经重写了equals。