关于equels与==
前言
在初学Java的时候,equels与==总是会感觉很混乱,这次特意来总结一下。首先来大致了解一下这两个的意思。
==作用是来判断两个对象是不是同一个对象,因为Java只有值传递,所以对于==来说不管是基本的数据类型还是引用的数据类型,其本质比较的都是值,只是引用的数据类型变量的值是对象的地址。所以就会容易搞混
equals方法也是比较两个对象是否相等。equals方法是Object类中的方法。
1
2
3
4//这是Object类中的equals方法
public boolean equals(Object obj){
return(this == obj);
}
在基本数据类型中的比较
基本数据类型不能算做为对象,所以并没有继承有equals的方法,所以只有==的比较
1 | int num1 = 15; |
在引用数据类型中的比较
String类型中的比较
String类型是重写了equals方法的,所以这里会经常弄乱,重写后的equals方法为
1 | public boolean equals(Object anObject) { |
不new String的情况
1 | String a = "ab"; |
为什么两个都是True,这就要关系到字符串常量池了。当进行第一条语句的时候,编译器就会先在字符串常量池寻找有没有”ab”这个字符串,若没有就会将这个字符串放入字符串常量池。第二条语句进行的时候,就可以找到”ab”这个字符串,就会把字符串常量池里的引用地址给b,所以a与b的字符串是同一个地址的,所以==是true的。在上面的String重写的equals方法可以看出,equals方法是比较内容是否相同,所以第二个也是true。
new String的情况
1 | String a = new String("ab"); |
new String的语句是在堆内存中开辟一块空间用来存放”ab”这个字符串,然后在栈中开辟一块a或b的空间放着字符串的对象的引用,所以a,b两个虽然内容相同,但其实是两个对象,所以地址是不一样的,==在引用中比较的就是对象的地址,结果就是false。String的equals方法是比较内容的,内容相同就是true
不在String中比较
1 | Scanner scanner = new Scanner(System.in); |
这个就比较容易理解了,因为equals方法没被重写,所以是比较两个对象是否是同一个对象,==比较两个地址是否是一样,也是比较是否为同一个对象,所以这两者的作用在equals方法没被重写的时候是一样的。
总结
在基本数据类型中
==比较两个值是否相同
在引用类型中
equals方法没被重写
==与equals方法比较的是两个的地址是否相同equals方法被重写,以String类举例
==比较地址,equals比较方法
一个特殊的例子
首先先看代码
1 | Integer num11 = 127; |
按照所想,在Integer类当中,==是比较两个是否是同一个地址,但上述的运行结果中却出现了一个false,接下来在进行以下测试
1 | Integer num11 = new Integer(127); |
由此可以看出
- 第一段代码中,在-128~127的范围中,==的结果是为true,而不在这个范围中,==则为false
- 第二段代码中,两个对象不一样,地址不一样,所以==的结果接就是就是false,没有任何异常的地方。
- 直接用Integer类型与Int类型作比较,值相等就为true
最后在寻找过后得到结果
Java对于Integer是有一种缓存机制的,缓存了-128到127之间的数字,有点类似String,所以在第一个例子中,num11与num22其实是共享一个地址的,所以==的结果是true,不在缓存范围外的数字,并不是共享一个地址,所以==的结果就为false