背景介绍
== 比较的是变量 (栈) 内存中存放的对象的 (堆) 内存地址, 用来判断两个对象的地址是否相同, 即是否是指相同一个对象. 比较的是真正意义上的指针操作.
equals 用来比较的是两个对象的内容是否相等, 由于所有的类都是继承自 java.lang.Object 类的, 所以适用于所有对象, 如果没有对该方法进行覆盖的话, 调用的仍然是 Object 类中的方法, 而 Object 中的 equals 方法返回的却是 == 的判断.
java 中的数据类型可以分为两类:
基本数据类型
byte,short,char,int,long,float,double,boolean
基本数据类型之间的比较需要用双等号(==), 因为他们比较的是值
引用数据类型
接口, 类, 数组等非基本数据类型
Java 中的字符串 String 属于引用数据类型. 因为 String 是一个类
当他们用 (==) 进行比较的时候, 比较的是他们在内存中的存放地址, 所以, 除非是同一个 new 出来的对象, 他们的比较后的结果为 true, 否则比较后结果为 false. 因为没 new 一次就会重新开辟一个新的堆内存空间
- Entity entity = new Entity();
- Entity entity1 = new Entity();
- Entity entity2 = entity;
- System.out.println(entity==entity2);
- System.out.println(entity.equals(entity2));
- System.out.println(entity.equals(entity1));
- System.out.println(entity==entity1);
执行结果
- true
- true
- false
- false
equals()方法介绍
Java 中所有的类都是继承与 Object 这个基类的, 在 Object 类中定义了一个 equals 方法, 这个方法的初始行为是比较对象的内存地址, 但在一些类库中已经重写了这个方法(一般都是用来比较对象的成员变量值是否相同), 比如: String,Integer,Date 等类中, 所以他们不再是比较类在堆中的地址了,
Object 类中源码
- public boolean equals(Object var1) {
- return this == var1;
- }
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;
- }
- }
总结:
对于复合数据类型之间进行 equals 比较, 在没有覆写 equals 方法的情况下, 他们之间的比较还是内存中的存放位置的地址值, 跟双等号 (==) 的结果相同; 如果被复写, 按照复写的要求来.
== 的作用:
基本类型: 比较的就是值是否相同
引用类型: 比较的就是地址值是否相同
equals 的作用:
引用类型: 默认情况下, 比较的是地址值, 重写该方法后比较对象的成员变量值是否相同
String 类的 equals()方法
在之前文章介绍 JVM 的时候, 提到过一个常量池, 这里咱们再来介绍下
- String a = "abc";// abc 在常量池中
- String b = "abc";// 栈中 b 指向常量池中的 abc
- String c = new String("abc");// 在堆内存中重新开辟了一个 abc 的空间
- String d = c.intern();// 检查字符串池里是否存在 "abc" 这么一个字符串, 如果存在, 就返回池里的字符串; 如果不存在, 该方法会 把 "abc" 添加到字符串池中, 然后再返回它的引用.
- System.out.println(a==b);
- System.out.println(a.equals(b));
- System.out.println(a==c);
- System.out.println(a.equals(c));
- System.out.println(a==d);
- System.out.println(a.equals(d));
- true
- true
- false
- true
- true
- true
关于常量池的描述可以看我这篇文章: 深入 java 虚拟机学习 -- 内存管理机制
来源: https://www.cnblogs.com/blueskyli/p/9932017.html