在java新手学习中,常常会遇到以下的问题:
//情况1:
int a=1;
int b=2;
System.out.println(a==b);
//情况2:
String str1 = "gogo";
String str2 = "gogo";
System.out.println(str1 == str2);
//情况3:
String str3=new String("gogo");
System.out.println(str1 == str3);
//情况4:
System.out.println(str1 .equals(str3));//这里就直接调用equals方法打印输出
打印结果如下:
true
true
false
true
为什么输出结果会是这样呢???
对此,就引出了我们今天的话题:为什么会出现这样的结果?以及出现这样结果的原因是什么?
在这里就需要我们对==与equals()的用法有具体的了解:
- == : 这是一个运算符,对于基本数据类型(byte,short,char,int,float,double,long,boolean)而言,由于存储在常量池中,所以在进行比较时直接进行值的比较。而对于引用数据类型,由于他们的存储分配在堆中,所以则会进行内存地址的比较。
- equals() : 是Object提供的一种方法,在String类中重写,用于对于String进行值(字符串内容)的比较。
我们来阅读一下其中equals()的源码:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
} //判断是否是String类型的实例
if (anObject instanceof String) {
String anotherString = (String)anObject; //强转为String类型
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; //有不同,返回false
i++;
}
return true; //否则默认返回true
}
}
return false;
}
情况1中:
int a与int b皆为基本数据类型,所以直接进行了比较,结果为true。
情况2中:
先定义了str1为"gogo",而后又定义了str2=“gogo”,这直接将str2引用指向String池中已经存在的“gogo”,不再重新创建对象,此时比较str1==str2,返回值true。
情况3中:
String str3 = new String(“gogo”)的实现过程:直接在堆中创建对象。如果后来又有String str4 = new String(“gogo”),str4不会指向之前的对象,而是重新创建一个对象并指向它,所以如果是执行str3==str4 则返回值是false,因为两个对象的地址不一样,如果是执行str3.equals(str4),返回true,因为内容相同。
情况4中:
直接调用equals()进行了内容值的比较,所以返回了true。