当前位置:编程学习 > JAVA >>

关于equals问题,小白求教

为什么用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); --------------------编程问答-------------------- 这明明是两个对象,不重写equals方法的话默认对象比较是比较的地址值。
所以返回false很正常。
至于你说的String
那会是因为String比较特殊吧,比较的不是地址值,而是字符串的值。 --------------------编程问答-------------------- 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方法。 --------------------编程问答--------------------
引用 1 楼 AA5279AA 的回复:
这明明是两个对象,不重写equals方法的话默认对象比较是比较的地址值。
所以返回false很正常。
至于你说的String
那会是因为String比较特殊吧,比较的不是地址值,而是字符串的值。

所有的类都继承自Object类,object中的equals比较的是地址,除非重写equals。
String类重写了equals使其比较内容,看一下源码就明白了
--------------------编程问答-------------------- 谢谢楼上帮助,明白了。非常感谢啊,csdn是个好地方 --------------------编程问答-------------------- String中的equals()也是被重写的,Object中的equals和==中一个效果,而==就是判断两个对象是不是指向同一个内存地址,所以你上面的那个不重写equals的话就是flase。如果不放心的话,你可以查看一下Object类的源代码,内部算法就是用==号来判断的。 --------------------编程问答--------------------
引用 5 楼 hjw506848887 的回复:
String中的equals()也是被重写的,Object中的equals和==中一个效果,而==就是判断两个对象是不是指向同一个内存地址,所以你上面的那个不重写equals的话就是flase。如果不放心的话,你可以查看一下Object类的源代码,内部算法就是用==号来判断的。

++ --------------------编程问答-------------------- 很高兴能帮助到你,String是个很特殊的类。你真的理解了String str1 = new String(“java”)吗,这句话其实生成了两个对象,一个是存放在堆内存里面的“java”,还有一个对象str1存放在栈内存里面,栈里面的str1指向对内存的具体对象。当执行String str2 = new String(“java”)这句话的时候,首先判断堆内存中是否存在“java”这个对象,查到存在了这个对象就不会在堆内存中生成了,只在栈内存中生成一个str2指向“java”这个对象,所以str1和str2的堆内存其实是一个东西,理解了吗? --------------------编程问答-------------------- 如果类不重写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;
}
--------------------编程问答-------------------- 可以看看java的帮助文档,看看String类的equals方法,再看看Object的equals方法,再进行比较就看出来啦嘻嘻 --------------------编程问答--------------------
引用 7 楼 qq1145174853 的回复:
很高兴能帮助到你,String是个很特殊的类。你真的理解了String str1 = new String(“java”)吗,这句话其实生成了两个对象,一个是存放在堆内存里面的“java”,还有一个对象str1存放在栈内存里面,栈里面的str1指向对内存的具体对象。当执行String str2 = new String(“java”)这句话的时候,首先判断堆内存中是否存在“java”这个对象,查到存在了这个对象就不会在堆内存中生成了,只在栈内存中生成一个str2指向“java”这个对象,所以str1和str2的堆内存其实是一个东西,理解了吗?


我的理解:
java 只要new 了,肯定会在堆上创建对象的。
str1 和 str2是两个对象。
您可以输出str1 ==str2,就会知道了。

而如果定义字符串 str3 = "java"; 
因为常量池已有"java"这个字符串了,所以就指向了那个地址而不创建新的对象了。 --------------------编程问答--------------------
引用 2 楼 samboy2002 的回复:
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方法。

拜托String不是基本类型吧 --------------------编程问答-------------------- 建议楼主去看看equals的源码,把它搞懂 --------------------编程问答-------------------- 对于引用类型来说,equals比较的是在堆内存中值,而==是比较栈内存中的值 --------------------编程问答--------------------
引用 7 楼 qq1145174853 的回复:
很高兴能帮助到你,String是个很特殊的类。你真的理解了String str1 = new String(“java”)吗,这句话其实生成了两个对象,一个是存放在堆内存里面的“java”,还有一个对象str1存放在栈内存里面,栈里面的str1指向对内存的具体对象。当执行String str2 = new String(“java”)这句话的时候,首先判断堆内存中是否存在“java”这个对象,查到存在了这个对象就不会在堆内存中生成了,只在栈内存中生成一个str2指向“java”这个对象,所以str1和str2的堆内存其实是一个东西,理解了吗?


你这水平就别来胡说八道。

对象str1?一个?

String a= new String(“java”);
String b= new String(“java”);

System.out.print(a==b);

你比较比较地址,看看是不是一个。 --------------------编程问答--------------------
引用 14 楼 forgetsam 的回复:
Quote: 引用 7 楼 qq1145174853 的回复:

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


你这水平就别来胡说八道。

对象str1?一个?

String a= new String(“java”);
String b= new String(“java”);

System.out.print(a==b);

你比较比较地址,看看是不是一个。


a和b在栈内存中是两个对象,在堆内存中只有一个对象,a和b同时指向一个对象,自己好好去看看string的原理吧 --------------------编程问答--------------------
引用 14 楼 forgetsam 的回复:
Quote: 引用 7 楼 qq1145174853 的回复:

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


你这水平就别来胡说八道。

对象str1?一个?

String a= new String(“java”);
String b= new String(“java”);

System.out.print(a==b);

你比较比较地址,看看是不是一个。

我又到网上看了下,貌似是我理解错了
栈(Stack) :存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中)。
  堆(heap):存放所有new出来的对象。
--------------------编程问答-------------------- Codsegment:存程序代码。
Datasegment:存静态变量或字符串常量。
Stack(栈):存局部变量。
Heap(堆):存new出来的对象。
Sting类的equals方法比较的是内容,==比较的是地址 是这样吗?这一块我也一直记不住,也迷惑,大神讲清楚点呗 --------------------编程问答--------------------
引用 2 楼 samboy2002 的回复:
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方法。

你概念错了
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
}
--------------------编程问答-------------------- 7楼说错了,String s1="java"
String s2 ="java"才是你说的情况,new出来的都是分配在堆上的,2个new出来的对象用==都是false
--------------------编程问答-------------------- 大家讲的都很好 --------------------编程问答-------------------- 这个问题其实我也碰到了 --------------------编程问答-------------------- 可以去了解下  字符串池  的概念。 --------------------编程问答--------------------
引用 7 楼 qq1145174853 的回复:
很高兴能帮助到你,String是个很特殊的类。你真的理解了String str1 = new String(“java”)吗,这句话其实生成了两个对象,一个是存放在堆内存里面的“java”,还有一个对象str1存放在栈内存里面,栈里面的str1指向对内存的具体对象。当执行String str2 = new String(“java”)这句话的时候,首先判断堆内存中是否存在“java”这个对象,查到存在了这个对象就不会在堆内存中生成了,只在栈内存中生成一个str2指向“java”这个对象,所以str1和str2的堆内存其实是一个东西,理解了吗?

正解 --------------------编程问答--------------------
引用 23 楼 nd707355117 的回复:
Quote: 引用 7 楼 qq1145174853 的回复:

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

正解

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

Quote: 引用 7 楼 qq1145174853 的回复:

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

正解

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

嗯,我之前直接当成a=“java”理解了,后来楼上一兄弟批评之后才发现弄错了 --------------------编程问答-------------------- String 对象重写equals方法,比较具体的内容。
而你写的Employee这个对象你没重写equals方法没比较具体的内容,默认比较内存地址自然不一样。
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,