用一句话来说就是:
“==”一般用在基本类型,“equals”一般用在引用类型。
在java中基本类型有八种,比较常用的是:int、float、double、boolean、char
除去基本类型之外的类型,即引用类型,编程员编写类对象不必说,初学者最容易把String类型当做基本类型,因此往往很容易出错。
代码胜千言,下面举出一些非常简单的例子:
int a = 9; int b = 9;
System.out.println(a == b); //基本类型,使用"==",输出为true
//在这里s1,s2的数据都是“静态区”的数据,因此也输出true
String s1 = "this is a test.";
String s2 = "this is a test.";
System.out.println(s1 == s2) ;
//输出false
String s1 = new String("this is a test.");
String s2 = "this is a test.";
System.out.println(s1 == s2) ;
这时候可能就会问了,上文说String是引用类型,那应该用“equals”啊,为什么用“==”号也行?为什么下面的s1与s2字符串内容一样,输出的东西是false?
看到这里一脸懵逼不要紧,我们再继续往下了解一些java的底层知识就可以解决了。
在java中有“栈”、“堆”、“静态存储区”的概念。
本文不详细展开解释这三者的定义,有能力的读者可以自行了解。读懂本文只需看懂下面这幅图,引用自链接,其中方法区即“静态存储区”,如果你还是不想看,不要紧,先继续往下看。
以上面第二个例子为例。
"this is a test."这个字符串存储在静态储存区中,且因为都是相同的字符串,因此地址是一模一样的,s1与s2指向的都是同一块变量,因此返回true,
如图(假设字符串地址为080):
现在看第三个例子。
由于s1中new了一个对象,因此他会在堆中产生一个新的对象指向静态存储区,因此在栈区存储的地址会发生变动。同样的,还是通过画图的方式更好理解:
与刚才第二个例子不同是s1先指向了堆区,堆区有一个地址为078。
078 == 080吗?
很明显,不是的。因此在第三个例子中直接用s1 == s2返回的是false。
接下来我们继续举一些简单的例子,来了解一些equals是什么原理。
//返回true
String s1 = new String("this is a test.");
String s2 = "this is a test.";
System.out.println(s1.equals(s2)) ;
我们这里把上述的第三个例子中的"=="号换成"equals"之后,程序返回的就是true了。
那么我们再自己新创建一个类,并用equals进行比较,会有什么样的结果呢?
class student{
private String name;
private int age;
public student(String name,int age) {
this.name = name;
this.age = age;
};
}
student d1 = new student("哈尔希洛",18);
student d2 = new student("哈尔希洛",18);
System.out.println(d1.equals(d2));
有兴趣的同学可以实现这一段代码就会发现,这个返回的是false,而不是true。
原因是:equals方法是java.lang.Object类继承的方法。
而java.lang.Object类中的equals方法是用于比较字符串是否相等的方法,如果不对在一个继承他的类中,并不是仅仅通过字符串比较而得到是否相同相同的结论,我们就必须对equals方法进行重写操作,以达到目的。
如以下代码:
//在一片代码的student类中加入一下代码
public boolean equals(student s){
if(this.age == s.age && this.name.equals(s.name)){
return true;
}
else {
return false;
}
}
我们重写equals类中,代码返回的便是true。
看到这里,大家应该都对“==”和“equals”有一个简单的了解。
总结就是:
1.碰见基本类型的比较,就用“连等”号。
2.碰见String类,就直接使用默认继承的equals方法即可。
3.如果是自己自定义的类,请重写一个equals方法,方便用于类之间的比较。