对象的比较 牢记:equals()是逻辑上比较==是引用的地址比较 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 object类的equals方法就是用的=来判断的!如果需要判断对象相等,而不是引用相等。需要在object的子类中override equals方法! 其实楼主主要的还是先明白 == 和equals 到底是属于什么相等== 号,直接比较值equals 则比较引用(reference/c++中的地址)但是对于 String 对象,java有一种不同的处理方式当你使用 s3 = "abc"; 和 s4 = "abc";的时间,java 先创建 abc这个String 对象, 而后把"abc"的引用(地址)赋给 s3和s4,所以s3==s4而当你使用 s1,s2,s3 = "abc"; 的时间, 创建s1和s2的时间,分别使用了s1 = new String("abc"); 这个时间重新创建一个String对象,他们的值相同,但地址都使用新的。因为当你使用s1,s2,s3 = "abc";的时间,你不希望他们指向同一个地址吧。 ==是判断引用是不是相同,也就是是不是指向了同一个内存区域equals 是比较内容是否相同的但是如果是你自己定义的类,默认的 equals方法是对引用的比较,所以结果可能令你吃惊,你需要覆盖 equals方法 呵呵,楼主出的分比较高,我来试着解释一下: 楼主看来对面向对象的内在细节不太了解。 记住一句话:引用永远放在栈上,而对象永远动态分配在堆上。 关于==和equals的区别其实深入到技术细节就是栈地址和堆地址的判断。 学JAVA你要搞清楚什么是简单的数据类型和什么是对象。 记住,在java中String就是一个类。 ==和equals的区别: ==用来判断引用地址是否相同,即判断是否引用(指针)指向同一个堆中的对象 而equals是判断对象内的数据是否相同,而不是地址了(不是指针指向的地址)。 System.out.println("s1=s2?"+(s1.equals(s2)));这个清楚了吧,内容相同为true System.out.println("s1=s3?"+(s1==s3));地址不同啊,为false System.out.println("s1=s3?"+(s1.equals(s3)));内容相同为true System.out.println("s3=s4?"+(s3==s4));呵,这个不是对象, 是普通的数据类型,就是值比较,为true System.out.println("s2=s3?"+(s2.equals(s3)));内容相同为true System.out.println("s2=s4?"+(s2.equals(s4)));内容相同为true System.out.println("obj1=obj2?"+(obj1.equals(obj2)));obj1引用指向的内容 在new后并没有进行赋值, 所以为假,即堆中的内容为 未知。为false System.out.println("s1=s2?"+(s1==s2));指向的栈地址不同啊,为false obj1=obj2;是引用赋值,即指针赋值 System.out.println("obj1=obj2 after obj1=obj2 ?"+(obj1.equals(obj2))); System.out.println("obj1=obj2 after obj1=obj2 ?"+(obj1==obj2)); 上面二个全是TRUE,因为引用赋值后,指向的同一个对象,引用指针内容为同。所以为TRUE。 JAVA是面向对象的东西,之所以还使用栈的东西是为了速度上的考虑,堆中虽然使用灵活,但效率的确是个大问题,编译器还得动态进行内存大小的配置,而栈中虽然不能动态配置大小,但却使用的速度非常快。各有得失,不知道楼上经我的解释是否明白。 我也是初学者,如果有错误还请指正,感谢!!!~~~~~~ to ghyghost(爱国人士--N年后,是否还残存一条▼~~~~) System.out.println("s3=s4?"+(s3==s4));呵,这个不是对象, 是普通的数据类型,就是值比较,为true 这个解释是错误的,s3和s4怎么不是Object,它们又是什么普通的数据类型s3="abc" 和s4 = "abc" 比较的还是引用比较(也就是地址比较),那他们为什么相等呢?因为Java在这里做了一个把戏,java先new String("abc")这时有一个引用了,而后把这个引用分别赋给s3和s4,这样就造成了s3==s4,你可以尝试比较 s3=="abc", s4=="abc",都为true 而当你使用 s1,s2,s3 = "abc"; 的时间, 创建s1和s2的时间,分别使用了s1 = new String("abc"); 这个时间重新创建一个String对象,他们的值相同,但地址都使用新的。因为当你使用s1,s2,s3 = "abc";的时间,你不希望他们指向同一个地址吧。 s1,s2,s3 = "abc";相当于s1 = new String("abc");s2 = new String("abc");s3 = "abc"; String s1,s2,s3="abc",s4="abc";s1=new String("abc");s2=new String("abc");s1,s2一开始没有初始化,而后才在s1=new String("abc");s2=new String("abc");后初始化的 其他的可以理解,现在还是老问题System.out.println("s3=s4?"+(s3==s4));这里按楼上的说法s3和s4不是普通的数据类型。他们是不是因为字符串池的缘故所以指向的是同一个地址?所以是true?可是我有本书上(“飞思--java2应用开发指南(第二版)”P103)上有一句是:对于同一类的的对象,==和equals方法返回值都为false。这个又如何理解呢?现在就是这里搞不清楚了!先谢了 to weimenren(宁静以致远,淡泊以明志) 您好,感谢您仔细看了我的回答 由于以前搞DELPHI的,所以在DELPHI中string类型就是一个普通的,这里还是沿用了老的思维,哈哈,没有改正过来,误人子弟!!~~~~~ 不过俺其它的都对了吧,就这处??感谢指正,不然我还是沿用老的思维。 引用 weimenren(宁静以致远,淡泊以明志)的答案:s3="abc" 和s4 = "abc" 比较的还是引用比较(也就是地址比较),那他们为什么相等呢?因为Java在这里做了一个把戏,java先new String("abc")这时有一个引用了,而后把这个引用分别赋给s3和s4,这样就造成了s3==s4,你可以尝试比较 s3=="abc", s4=="abc",都为true 刚才在机器上试了一下,的确如此,呵呵,看来初学JAVA二天的我还要努力,感谢 weimenren(宁静以致远,淡泊以明志)。 如果是这样:public class Hello { public static void main(String[] ghyghost) { String a="123",b="456"; System.out.println(a==b); }}结果就为false,看来java编译器在往堆中送值时还要验证一下是否有值相同,如果相同就指向同一个地址,如果不同则异地址再来一灌:public class Hello { public static void main(String[] ghyghost) { String a="123",b="123"; System.out.println(a==b); b="4565"; System.out.println(a==b); }}再次改变对象b的值后,结果为false,说明改变b的值则在堆中重新建立一个地址空间,所以为false....这是我总结的,不知道对否,呵呵,还请高手指点。。~~~~~ ^^ 你的两个对象obj1和obj都是指向堆里面的同一个地址,所以system.out.println(obj1==obj2) 的表达式结果是真,如果你在声明一个class B{int a=1;} A obj1=new A();B obj2=new B();System.out.println(obj1=obj2);输出的旧是false;同样,你把String看成对象,是申明了4个不同的对象,他们分别有着不同的内存地址,分别给他们负值“abc”在运算符是“==” 的时候java实质上是对他们的地址进行比较,所以返回的是false,而用equals时时用他们的值比较所以return true; 旭林的回贴其实就是一个作用域范围访问的问题,不属于同一个类的对象,存储数据的地址空间也不同(在有相同赋值的情况下,例如:s3="abc",s4="abc")。 == 和equalsString类把object的equals覆写了!大家可以看看他的覆写就知道了。注意如果String str = “”;if(str.equals(""))那样会exception 。如果用过Hashtable的话就知道了,Hashtable必须覆盖Object的equals()和hashCode();看下面的例子:class A { private String str_name = null; private int int_age = 0; public A(String str, int i){ str_name = str; int_age = i; } public boolean equals(Object o){ if(o instanceof A){ A aTemp = (A)o; if(str_name.equals(aTemp.name)&&int_age == aTemp.int_age){ return true; }else { return false; } }else{ return false; } } public int hashCode(){ ..... } }自己体会去吧! 越说越乱了,==是引用比较,而equals()是自定义的逻辑比较,具体结果全看怎么定义equals了,如果不写equals,默认的Object.equals(Object o) { return this==o; }和==是一个效果至于string:s1 = "abc"; 这个"abc"放在静态堆内存中,编译期就确定了如果再有一个s2 = "abc"; 如果编译器足够优化,看出两个"abc"是一样的,就只需要在静态堆内存中分配一份,于是s1==s2=true,否则s1==s2=falses = "abc";和 s=new String("abc");有很大不同:"abc"本身就是一个String对象s="abc"并没有创建新对象,只是让s指向"abc"对象s=new String("abc")是创建一个新的string,它的内容和参数"abc"一样 ant的taskdef怎么使用 Java API有显示n个数的排列 组合的函数吗! 哪位朋友有这样的源代码? 在JSP中如何连接数据库? 想再看看机械出版出的《Java 程序设计》,请问网上有下的电子文档吗,? 如何复制图片? double数据类型精度问题求教 怎么获得查询返回的值呢(急!!!!!!!!) 那位高人能提供关于Jbuilder的学习教材下载!!!!!急急急!!!!! Java菜鸟求助关于ArrayList转数组的问题 java函数写法问题?其实是异常问题 急,最后一步出错了!
equals 则比较引用(reference/c++中的地址)但是对于 String 对象,java有一种不同的处理方式当你使用 s3 = "abc"; 和 s4 = "abc";的时间,java 先创建 abc这个String 对象, 而后把"abc"的引用(地址)赋给 s3和s4,所以s3==s4而当你使用 s1,s2,s3 = "abc"; 的时间, 创建s1和s2的时间,分别使用了s1 = new String("abc"); 这个时间重新创建一个String对象,他们的值相同,但地址都使用新的。因为当你使用s1,s2,s3 = "abc";的时间,你不希望他们指向同一个地址吧。
equals 是比较内容是否相同的但是如果是你自己定义的类,默认的 equals方法是对引用的比较,所以结果可能令你吃惊,你需要覆盖 equals方法
记住一句话:引用永远放在栈上,而对象永远动态分配在堆上。
关于==和equals的区别其实深入到技术细节就是栈地址和堆地址的判断。
学JAVA你要搞清楚什么是简单的数据类型和什么是对象。
记住,在java中String就是一个类。
==和equals的区别:
==用来判断引用地址是否相同,即判断是否引用(指针)指向同一个堆中的对象
而equals是判断对象内的数据是否相同,而不是地址了(不是指针指向的地址)。
System.out.println("s1=s2?"+(s1.equals(s2)));这个清楚了吧,内容相同为true
System.out.println("s1=s3?"+(s1==s3));地址不同啊,为false
System.out.println("s1=s3?"+(s1.equals(s3)));内容相同为true
System.out.println("s3=s4?"+(s3==s4));呵,这个不是对象,
是普通的数据类型,就是值比较,为true
System.out.println("s2=s3?"+(s2.equals(s3)));内容相同为true
System.out.println("s2=s4?"+(s2.equals(s4)));内容相同为true
System.out.println("obj1=obj2?"+(obj1.equals(obj2)));obj1引用指向的内容
在new后并没有进行赋值,
所以为假,即堆中的内容为
未知。为false
System.out.println("s1=s2?"+(s1==s2));指向的栈地址不同啊,为false
obj1=obj2;是引用赋值,即指针赋值
System.out.println("obj1=obj2 after obj1=obj2 ?"+(obj1.equals(obj2)));
System.out.println("obj1=obj2 after obj1=obj2 ?"+(obj1==obj2));
上面二个全是TRUE,因为引用赋值后,指向的同一个对象,引用指针内容为同。所以为TRUE。 JAVA是面向对象的东西,之所以还使用栈的东西是为了速度上的考虑,堆中虽然使用灵活,但效率的确是个大问题,编译器还得动态进行内存大小的配置,而栈中虽然不能动态配置大小,但却使用的速度非常快。各有得失,不知道楼上经我的解释是否明白。
我也是初学者,如果有错误还请指正,感谢!!!~~~~~~
是普通的数据类型,就是值比较,为true
这个解释是错误的,s3和s4怎么不是Object,它们又是什么普通的数据类型s3="abc" 和s4 = "abc" 比较的还是引用比较(也就是地址比较),那他们为什么相等呢?因为Java在这里做了一个把戏,java先new String("abc")这时有一个引用了,而后把这个引用分别赋给s3和s4,这样就造成了s3==s4,你可以尝试比较 s3=="abc", s4=="abc",都为true
s2 = new String("abc");
s3 = "abc";
s1=new String("abc");
s2=new String("abc");s1,s2一开始没有初始化,而后才在s1=new String("abc");
s2=new String("abc");后初始化的
这里按楼上的说法s3和s4不是普通的数据类型。他们是不是因为字符串池的缘故所以指向的是同一个地址?所以是true?可是我有本书上(“飞思--java2应用开发指南(第二版)”P103)上有一句是:对于同一类的的对象,==和equals方法返回值都为false。这个又如何理解呢?现在就是这里搞不清楚了!
先谢了
s3="abc" 和s4 = "abc" 比较的还是引用比较(也就是地址比较),那他们为什么相等呢?因为Java在这里做了一个把戏,java先new String("abc")这时有一个引用了,而后把这个引用分别赋给s3和s4,这样就造成了s3==s4,你可以尝试比较 s3=="abc", s4=="abc",都为true 刚才在机器上试了一下,的确如此,呵呵,看来初学JAVA二天的我还要努力,感谢 weimenren(宁静以致远,淡泊以明志)。
String a="123",b="456";
System.out.println(a==b);
}
}
结果就为false,看来java编译器在往堆中送值时还要验证一下是否有值相同,如果相同就指向同一个地址,如果不同则异地址再来一灌:
public class Hello { public static void main(String[] ghyghost) {
String a="123",b="123";
System.out.println(a==b);
b="4565";
System.out.println(a==b);
}
}再次改变对象b的值后,结果为false,说明改变b的值则在堆中重新建立一个地址空间,所以为false....这是我总结的,不知道对否,呵呵,还请高手指点。。~~~~~ ^^
A obj1=new A();
B obj2=new B();
System.out.println(obj1=obj2);输出的旧是false;
同样,你把String看成对象,是申明了4个不同的对象,他们分别有着不同的内存地址,分别给他们负值“abc”在运算符是“==” 的时候java实质上是对他们的地址进行比较,所以返回的是false,而用equals时时用他们的值比较所以return true;
String类把object的equals覆写了!大家可以看看他的覆写就知道了。
注意如果String str = “”;
if(str.equals(""))那样会exception 。
如果用过Hashtable的话就知道了,Hashtable必须覆盖Object的equals()和hashCode();
看下面的例子:
class A {
private String str_name = null;
private int int_age = 0;
public A(String str, int i){
str_name = str;
int_age = i;
} public boolean equals(Object o){
if(o instanceof A){
A aTemp = (A)o;
if(str_name.equals(aTemp.name)&&int_age == aTemp.int_age){
return true;
}else {
return false;
}
}else{
return false;
}
} public int hashCode(){
.....
}
}自己体会去吧!
s1 = "abc"; 这个"abc"放在静态堆内存中,编译期就确定了
如果再有一个
s2 = "abc"; 如果编译器足够优化,看出两个"abc"是一样的,就只需要在静态堆内存中分配一份,于是s1==s2=true,否则s1==s2=falses = "abc";和 s=new String("abc");有很大不同:
"abc"本身就是一个String对象
s="abc"并没有创建新对象,只是让s指向"abc"对象
s=new String("abc")是创建一个新的string,它的内容和参数"abc"一样