为什么用String类声明的对象去调用equals方法会返回true
比如String str1 = new String(“java”)
    String str2 = new String(“java”)
这个返回的是ture
但是下面的这个语句一定要重写equals中的方法才返回ture,不然就是false
Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15);
Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15);

解决方案 »

  1.   

    这明明是两个对象,不重写equals方法的话默认对象比较是比较的地址值。
    所以返回false很正常。
    至于你说的String
    那会是因为String比较特殊吧,比较的不是地址值,而是字符串的值。
      

  2.   

    String是JAVA的基本类型,所有的字符串都是共享的,也就是说你的str1和str2虽然是new了两次,但实际上是一个对象实例,所以equals是true.
    这个涉及到JVM对基本类型管理的知识了,JAVA中有很多类似的地方,例如:List a = new ArrayList(0);
    List b = new ArrayList(0);

    System.out.print(a.equals(b)); // output true
    我们自己定义的类一般是每次new的时候都会创建一个新的实例,所以要重写equals方法。
    另外,重写equals方法,必须同时重写hashCode方法。
      

  3.   

    所有的类都继承自Object类,object中的equals比较的是地址,除非重写equals。
    String类重写了equals使其比较内容,看一下源码就明白了
      

  4.   

    谢谢楼上帮助,明白了。非常感谢啊,csdn是个好地方
      

  5.   

    String中的equals()也是被重写的,Object中的equals和==中一个效果,而==就是判断两个对象是不是指向同一个内存地址,所以你上面的那个不重写equals的话就是flase。如果不放心的话,你可以查看一下Object类的源代码,内部算法就是用==号来判断的。
      

  6.   

    很高兴能帮助到你,String是个很特殊的类。你真的理解了String str1 = new String(“java”)吗,这句话其实生成了两个对象,一个是存放在堆内存里面的“java”,还有一个对象str1存放在栈内存里面,栈里面的str1指向对内存的具体对象。当执行String str2 = new String(“java”)这句话的时候,首先判断堆内存中是否存在“java”这个对象,查到存在了这个对象就不会在堆内存中生成了,只在栈内存中生成一个str2指向“java”这个对象,所以str1和str2的堆内存其实是一个东西,理解了吗?
      

  7.   

    如果类不重写equals方法,模式使用Object的实现,而Object实现就是比较引用地址的。
    String类重写的equals方法:依次比较每个位置的字符是否相等。
    等你自己的类Employee没有重写equals,所以比较的是地址。附 String的equals实现:public boolean equals(Object anObject) {
    if (this == anObject) {
    return true;
    }
    if (anObject instanceof String) {
    String anotherString = (String) anObject;
    int n = count;
    if (n == anotherString.count) {
    char v1[] = value;
    char v2[] = anotherString.value;
    int i = offset;
    int j = anotherString.offset;
    while (n-- != 0) {
    if (v1[i++] != v2[j++])
    return false;
    }
    return true;
    }
    }
    return false;
    }
      

  8.   

    可以看看java的帮助文档,看看String类的equals方法,再看看Object的equals方法,再进行比较就看出来啦嘻嘻
      

  9.   


    我的理解:
    java 只要new 了,肯定会在堆上创建对象的。
    str1 和 str2是两个对象。
    您可以输出str1 ==str2,就会知道了。而如果定义字符串 str3 = "java"; 
    因为常量池已有"java"这个字符串了,所以就指向了那个地址而不创建新的对象了。
      

  10.   

    建议楼主去看看equals的源码,把它搞懂
      

  11.   

    对于引用类型来说,equals比较的是在堆内存中值,而==是比较栈内存中的值
      

  12.   


    你这水平就别来胡说八道。对象str1?一个?String a= new String(“java”);
    String b= new String(“java”);System.out.print(a==b);你比较比较地址,看看是不是一个。
      

  13.   


    你这水平就别来胡说八道。对象str1?一个?String a= new String(“java”);
    String b= new String(“java”);System.out.print(a==b);你比较比较地址,看看是不是一个。a和b在栈内存中是两个对象,在堆内存中只有一个对象,a和b同时指向一个对象,自己好好去看看string的原理吧
      

  14.   


    你这水平就别来胡说八道。对象str1?一个?String a= new String(“java”);
    String b= new String(“java”);System.out.print(a==b);你比较比较地址,看看是不是一个。
    我又到网上看了下,貌似是我理解错了
    栈(Stack) :存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中)。
      堆(heap):存放所有new出来的对象。
      

  15.   

    Codsegment:存程序代码。
    Datasegment:存静态变量或字符串常量。
    Stack(栈):存局部变量。
    Heap(堆):存new出来的对象。
    Sting类的equals方法比较的是内容,==比较的是地址 是这样吗?这一块我也一直记不住,也迷惑,大神讲清楚点呗
      

  16.   

    你概念错了
    1、String 不是基本类型,JAVA中的基本类型只有8种:byte, short, int, long, char, float, double, boolean。
    2、str1和str2虽然是new了两次,他们是两个不同的实例,JAVA每个new操作都是新的实例。可以使用str1 == str2来验证是否是同一个实例。这段代码弄懂了就能对String有更深的了解了 public static void main(String[] args) {
    String s1 = "abc";
    String s2 = new String("abc");
    String s3 = "a" + "bc";
    String s4 = "a" + new String("bc");

    System.out.println(s1 == s2); //false
    System.out.println(s1 == s3); //true
    System.out.println(s1 == s4); //false
    System.out.println(s1 == s4.intern()); //true
    }
      

  17.   

    7楼说错了,String s1="java"
    String s2 ="java"才是你说的情况,new出来的都是分配在堆上的,2个new出来的对象用==都是false
      

  18.   

    正解
    上面的是我看错了,如果是new 出来的地址肯定不一样!String str1 = new String(“java”)对于这句话我的理解是,现在栈中存放了str1这个引用变量,指向堆中的java ,而对中的java是复制的常量池中的java,所以说这句代码其实是产生了两个java,一个在常量池中,而在堆中的则是复制的常量池里的
      

  19.   

    正解
    上面的是我看错了,如果是new 出来的地址肯定不一样!String str1 = new String(“java”)对于这句话我的理解是,现在栈中存放了str1这个引用变量,指向堆中的java ,而对中的java是复制的常量池中的java,所以说这句代码其实是产生了两个java,一个在常量池中,而在堆中的则是复制的常量池里的
    嗯,我之前直接当成a=“java”理解了,后来楼上一兄弟批评之后才发现弄错了
      

  20.   

    String 对象重写equals方法,比较具体的内容。
    而你写的Employee这个对象你没重写equals方法没比较具体的内容,默认比较内存地址自然不一样。