区别
== 是java提供的等于比较运算符,用来比较两个变量指向的内存地址是否相同.而equals()是Object提供的一个方法.Object中equals()方法的默认实现就是返回两个对象==的比较结果.但是equals()可以被重写,所以我们在具体使用的时候需要关注equals()方法有没有被重写
什么是==?
== 等于比较运算符,如果进行比较的两个操作数都是数值类型,即使他们的数据类型不相同,只要他们的值相等,也都将返回true.如果两个操作数都是引用类型,那么只有当两个引用变量的类型具有父子关系时才可以比较,而且这两个引用必须指向同一个对象,才会返回true.(在这里我们可以理解成==比较的是两个变量的内存地址)
什么是equals()?
equals()方法是Object类的方法,在Object类中的equals()方法体内实际上返回的就是使用==进行比较的结果.但是我们知道所有的类都继承Object,而且Object中的equals()方法没有使用final关键字修饰,那么当我们使用equal()方法进行比较的时候,我们需要关注的就是这个类有没有重写Object中的equals()方法.
==来说:
如果比较的是基本数据类型变量,比较两个变量的值是否相等。(不一定数据类型相同)
如果比较的是引用数据类型变量,比较两个对象的地址值是否相同,即两个引用是否指向同一个地址值
当为基本数据类型时:
int a = 20;
double c = 20.0;
char i = 20;
char j = 'A';
char m = 65;
boolean boo = true;
System.out.println(c==a);//true
System.out.println(a==i);//true
System.out.println(j==m);//true
System.out.println(boo==a);//编译不通过
当为引用数据类型时:
package HelloWorld;
public class testt {
public static void main(String[] args) {
String s1 = "song";
String s2 = "song";
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
}
}
第二种:
package HelloWorld;
public class testt {
public static void main(String[] args) {
String s1 = "song";
String s2 = new String("song");
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
}
}
结果:
false
true
解析:
第一种,在编译String s1 =“song”的时候,JVM会在常量池 创建一个内容为song的地址值,然后让s1 去指向 song。而不是直接把song赋值给 s1 ,
然后再编译String s2 = “song”时,常量池中已经有song这个地址值了,所以,直接将s2指向这个song,他们所指向的地址值是相同的。
所以 == 是比较的地址值
而第二种,String s2 = new String ("song")是创建的一个新的对象,每创建一个新的对象都会在堆内存里开辟一个新的空间去存储这个song,所以 他们的地址值是不一样的。
当两个都是创建对象时:
1.
package HelloWorld;
public class testt {
public static void main(String[] args) {
testt t = new testt(12,"张旭");
testt t1 = new testt(12,"张旭");
System.out.println(t == t1);
}
private int age ;
private String name ;
public testt(int age , String name) {
this.age = age ;
this.name = name ;
}
}
结果为:false ,
原因是: 虽然两个对象的属性值都相等,但系统每new一个对象都会创建一个新的地址值,所以两个的地址不一样。
2.
String str = new String("hello");
String str2 = new String("hello");
System.out.println(str.equals(str2));//true
但同样的new两个对象,这个却是true ?
原因是String类会对equals方法进行重写。
源码如下
public boolean equals(Object anObject) {
//判断调用equals方法的对象和 形参引用地址是否相等
if (this == anObject) {
return true;
}
//判断左边形参引用是否是右边String类的实例对象
if (anObject instanceof String) {
//将形参引用强制转换为String对象
String anotherString = (String)anObject;
//获取字符串长度
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}