前言
== 和 equals 是咱们面试中常常会碰到的问题。那么它们之间有什么分割和区别呢?明天咱们就来聊聊吧!
问题
这里先抛出一些比拟典型口试问题:
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
- 这里为什么会是 true 呢?按理说 str3 和 str4 是两个对象,”==” 比拟的是地址,应该会是 false 才对。如果你是这么想的,那你就不是很理解 String 类。String 类,咱们都晓得它是不可变的字符序列,存储在常量池中,所以当你申明了一个 str3=”abc” 时,就会在常量池中开拓一个内存空间来寄存 ”abc”,下次再申明时,就会在常量池中去找,有,就间接把以后地址赋给变量,没有,就再创立。因而,此处的 str3 和 str4 是指向的同一个内存地址。
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 调用包装类的构造方法来创建对象。
此处以 Integer 类为例,源码参考:
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 学习路线图,于是我依据本人的教训,利用业余时间熬夜肝了一个月,整顿了一份电子书。无论你是面试还是自我晋升,置信都会对你有帮忙!
收费送给大家,只求大家金指给我点个赞!
电子书 | Linux 开发学习路线图
也心愿有小伙伴能退出我,把这份电子书做得更完满!
有播种?心愿老铁们来个三连击,给更多的人看到这篇文章
举荐浏览:
- 干货 | 程序员进阶架构师必备资源免费送
- 神器 | 反对搜寻的资源网站