今天和朋友聊面试经历聊到了这个话题,其实这是一个特别简单的基础问题,就是比较容易混,所以我稍微整理了一下。
== 的运行机制
若是基本数据类型,则判断它们的内容是否相等;
若是对象,则判断它们的地址是否相等。
equals()的运行机制
可分为以下三种情况讨论:
1.八大基本数据类型的包装类
使用equals()方法进行比较,比较的是它们的内容值;
例:
Integer a = 1;
Integer b = 1;
System.out.println(a.equals(b));
结果返回true;
创建两个Integer对象,使用equals()方法进行判断,返回true。查看相应的equals源码,可看出执行过程中将获得两个对象的内容值,然后比较。
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return this.value == (Integer)obj;
} else {
return false;
}
}
2.String数据类型
这里讲到String,因为它不属于八大基本数据类型,但我们经常使用到它。
String调用.equals()方法同样也是值的比较。
String aa = "AVC";
String bb = "AVC";
System.out.println(aa.equals(bb));
结果返回true;
点击查看.equals()的源码可以看到以下内容:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
} else {
if (anObject instanceof String) {
String aString = (String)anObject;
if (this.coder() == aString.coder()) {
return this.isLatin1() ? StringLatin1.equals(this.value, aString.value) : StringUTF16.equals(this.value, aString.value);
}
}
return false;
}
}
可以看出这是一个内容值的比较,这时候就有朋友好奇了,那里面的StringLatin1.equals(this.value, aString.value) 的equals 比较的是什么呢?
我们点击源码继续看:
@HotSpotIntrinsicCandidate
public static boolean equals(byte[] value, byte[] other) {
if (value.length == other.length) {
for(int i = 0; i < value.length; ++i) {
if (value[i] != other[i]) {
return false;
}
}
return true;
} else {
return false;
}
}
在这里可看出该方法对该String逐个取出字符并进行比较!毕竟String的底层是用char来实现的。
注:
- 关于以下两个字符串==比较结果为ture的讲解。
Stirng a = "aaa";
Stirng b = "aaa";
System.out.pringln(a==b);//结果为true
首先, == 比较的是地址。
上述的String a创建的时候将内容"aaa"存放在JVM的字符串常量池中,而String a引用”aaa“的地址。
而String b 创建的时候首先会将内容在JVM的字符串常量池中寻找是否存在,若存在,则直接引用该内容的地址,若不存在,则直接新建新的内容。
所以String a 和String b 引用的都是同一个 地址,即JVM下的字符串常量池的”aaa“的地址。
3.自己编写的类对象
自己编写的类对象,equals()方法比较的是地址。
例:
Student a1 = new Student();
Student a2 = new Student();
System.out.println(a1.equals(a2));
这里的返回结果是false,点击equals源码可以看到:
public boolean equals(Object obj) {
return this == obj;
}
源码中是直接使用==来进行比较,所以是对地址的比较。
若是想比较内容,则需要在Student重写.equals()方法。