您的位置:首页 > 编程语言 > Java开发

java基础学习之 equals 和 == 的用法与区别

2018-09-13 18:37 393 查看
最近碰到好几个关于equals 和 == 的使用判断问题,自己通过网上查询总结了一下。本文主要参考了

https://www.geek-share.com/detail/2692035674.html
https://www.geek-share.com/detail/2720441014.html
https://www.geek-share.com/detail/2675096183.html
等文章。

**

1.“==”的用法

**
对于“==”我们应该很熟悉,一般用来比较两个值是否相等。那这个值是什么呢?
可以分两种情况:
(1)对于基本数据类型。
byte,short,char,int,long,float,double,boolean,他们之间的比较是他们的值。(看的就是值的大小)**
比如:

int a = 10;
double b = 10.0;
long c = 10;
System.out.println(a == b);//ture
System.out.println( b == c);//ture

结果都是正确的,与数据类型无关;
注意:对于基本数据类型,是只能用“==”的,equals会报错;
例如同样的

int a = 10;
int m =10;
System.out.println(a.equals(m));

这里a.equals(m),是会直接报错。

(2)复合数据类型
当用 “==”进行比较的是他们在内存中的存放地址,我们知道,当我们new了一个对象时,它是在堆中开辟了一个内存,而栈中存的是指向对象的地址。所以“==”比较的就是地址。
所以除非是同一个new出来的对象,他们的地址是相同的,比较后的结果为true,否则比较后结果为false。
例如:

class Demo {
}
class Main {
public static void main(String[] args)
{
Demo a = new Demo();
Demo b = new Demo();
Demo c  =a;
System.out.println(a==b); //false
System.out.println(a==c);//true
}
}

**

2. equals的用法:

**

**equals方法最初是在所有类的基类Object中进行定义的,源码是

public boolean equals(Object obj) {
return (this == obj);
}

由equals的源码可以看出这里定义的equals与==是等价的。用于比较对象的内存地址。**

例如:

class Demo {
}
class Main {
public static void main(String[] args)
{
Demo a = new Demo();
Demo b = new Demo();
Demo c = a;
System.out.println(a.equals(b));//false
System.out.println(a.equals(c));//true
}
}

* 但是,存在一个特殊情况。在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。*
比如在String类中equals重写成了:

1     public boolean equals(Object anObject) {
2     if (this == anObject) {
3         return true;
4     }
5     if (anObject instanceof String) {
6         String anotherString = (String)anObject;
7         int n = count;
8         if (n == anotherString.count) {
9         char v1[] = value;
10         char v2[] = anotherString.value;
11         int i = offset;
12         int j = anotherString.offset;
13         while (n-- != 0) {
14             if (v1[i++] != v2[j++])
15             return false;
16         }
17         return true;
18         }
19     }
20     return false;
21     }

**另外:根据创建对象的方式不同也要分为两种:
1.是new,在堆中新创建一个对象。
2.使用表达式创建。如String s=”abc”,,它是在常量池中创建而不是像new一样放在堆中。这种形式的字符串,在JVM内部发生字符串拘留,即当声明这样的一个字符串后,JVM会在常量池中先查找有没有一个值为”abc”的对象,如果有,就会把它赋给当前引用.即原来那个引用和现在这个引用指向了同一对象,如果没有,则在常量池中新创建一个”abc”,下一次如果有String s1 = “abc”;又会将s1指向”abc”这个对象,即以这形式声明的字符串,只要值相等,任何多个引用都指向同一对象。
**
所以在下面的例子中

class  Main{
public static void main(String[] args)
{
String s1 = "abc";//创建了一个abc的字符串
String s2 = "abc";//先查找常量池,发现存在了abc,所以s2 和S1 指向同一个abc
String s3 = new String("abc");//在堆中建立了一个abc的对象

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

因为s1和s2是指向同一个“abc”,所以s1 == s2,s1.equals(s2)的输出是true;而s1和s3指向不同的“abc”,地址不同,所以s1 == s3是false。注意最后的s1.equals(s3)结果是true,这是因为String类对该方法进行了覆写,使其不再比较的是地址,而是对象的具体内容。由于S1 和S3都是“abc”的字符串,所以相等,结果为true。

简单点总结
1. 基本数据类型只有==,用于比较值;
2.对于复合数据类型(包括类):当equals被重写了,如在String类时,== 比较的是地址;equals比较的变成了对象的内容。
而当equals未覆盖,如new 一个类时,equals和 == 等价。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: