==和equals是咱们面试中常常会碰到的问题。那么它们之间有什么联系和区别呢?今天咱们就来聊聊吧!java
这里先抛出一些比较典型笔试问题:程序员
int x = 10;
int y = 10;
String str1 = new String("abc");
String str2 = new String("abc");
String str3 = "abc";
String str4 = "abc";
System.out.println(x == y); // 输出?
System.out.println(str1 == str2); // 输出?
System.out.println(str1.equals(str2)); // 输出?
System.out.println(str3 == str4); // 输出?
System.out.println(str1 == str3); // 输出?
System.out.println(str1.equals(str3)); // 输出?
Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
System.out.println(f1 == f2);// 输出?
System.out.println(f3 == f4);// 输出?复制代码
咱们一般就是说"=="用来判断两个变量之间的的值是否相等。变量又分为基本数据类型变量和引用类型。若是是基本数据类型的变量直接比较值而引用类型要比较对应的引用的内存的首地址。而equals方法 通俗来讲就是用来比较两个对象长得是否同样。判断两个对象的某些特征(内容)是否同样。实际上就是调用对象的equals方法进行比较。那么咱们来看看equals方法吧!面试
equals方法实际上是属于Object类的方法。由于Object类是全部类的直接或间接父类,也就是说全部的类中的equals()方法都继承自Object类,而经过源码咱们发现,Object类中equals()方法底层实现其实就是是"=="号。数组
public boolean equals(Object obj) {
return (this == obj);
}复制代码
那么,在全部没有重写equals()方法的类中,调用equals()方法其实和使用"=="号的效果同样,也是比较的对象地址值,然而,Java提供的全部类中,绝大多数类都重写了equals()方法,重写后的equals()方法通常都是比较两个对象的值,好比String类,Date类,基本数据类型的包装类等。能够看哈String类的源码:缓存
public boolean equals(Object var1) {
if (this == var1) {
return true;
} else {
if (var1 instanceof String) {
String var2 = (String)var1;
int var3 = this.value.length;
if (var3 == var2.value.length) {
char[] var4 = this.value;
char[] var5 = var2.value;
for(int var6 = 0; var3-- != 0; ++var6) {
if (var4[var6] != var5[var6]) {
return false;
}
}
return true;
}
}
return false;
}
}复制代码
看了上面的描述,相信你能够作对或者回答起大多数这类的问题。可是还须要注意如下两点:架构
String str3 = "abc";
String str4 = "abc";
System.out.println(str3 == str4); // 输出true复制代码
Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
System.out.println(f1 == f2);// 输出true
System.out.println(f3 == f4);// 输出false复制代码
看到上面的答案是否是感到十分的诧异。其实这里隐藏着一个知识点。就是包装类的缓存问题。下面简单描述一下:学习
整型、char类型所对应的包装类,在自动装箱时,对于-128~127之间的值会进行缓存处理。固然其目的就是提升效率。网站
缓存处理的原理为:若是数据在-128~127这个区间,那么在类加载时就已经为该区间的每一个数值建立了对象,并将这256个对象存放到一个名为cache的数组中。每当自动装箱过程发生时(或者手动调用valueOf()时),就会先判断数据是否在该区间,若是在则直接获取数组中对应的包装类对象的引用,若是不在该区间,则会经过new调用包装类的构造方法来建立对象。this
此处以Integer类为例,源码参考:spa
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i); // 超过范围就是new的Integer对象
}复制代码
这段代码中咱们须要解释下面几个问题:
1. IntegerCache类为Integer类的一个静态内部类,仅供Integer类使用,做用就是初始化数组cache的,这个过程会在类加载时完成。感兴趣能够去看哈源码,这里就再也不粘贴了。
2. 通常状况下 IntegerCache.low为-128,IntegerCache.high为127,IntegerCache.cache为内部类的一个静态属性。复制代码
看到这,相信你对上面抛出的问题,已经能够迎刃而解。答案参考:
int x = 10;
int y = 10;
String str1 = new String("abc");
String str2 = new String("abc");
String str3 = "abc";
String str4 = "abc";
System.out.println(x == y); // 输出true
System.out.println(str1 == str2); // 输出false
System.out.println(str1.equals(str2)); // 输出true
System.out.println(str3 == str4); // 输出true
System.out.println(str1 == str3); // 输出false
System.out.println(str1.equals(str3)); // 输出true
Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
System.out.println(f1 == f2);// 输出true
System.out.println(f3 == f4);// 输出false复制代码
最后,最近不少小伙伴找我要Linux学习路线图,因而我根据本身的经验,利用业余时间熬夜肝了一个月,整理了一份电子书。不管你是面试仍是自我提高,相信都会对你有帮助!目录以下:
免费送给你们,只求你们金指给我点个赞!
也但愿有小伙伴能加入我,把这份电子书作得更完美!
推荐阅读: