【面试篇】Java中==和equals的区别是什么?
每天进步一点点!
==
的解读:
- 如果用作基本数据类型的变量,则比较的是其存储的值是否相等。
- 如果用作引用类型的变量,则比较的是所指向的对象的地址。
equals
的解读:
- equals方法是基类Object中的实例方法,对所有继承与Object的类都会有该方法,其比较的是对象
- 如果类没有对equals方法进行重写,那么就是
==
, 即比较的对象的地址 - 如果类对equals方法进行了重写,一般用来比较两个对象的内容是否相等。如String中的equals()是被重写了,比较的是对象的值。
例子
public static void main(String[] args) {
//基本数据类型的比较
int num1 = 10;
int num2 = 10;
System.out.println(num1 == num2); //true
//引用数据类型的比较
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); //true
System.out.println(s1.equals(s2)); //true
//String类中==与equals的比较
String s3 = new String("hello");
String s4 = new String("hello");
System.out.println(s3 == s4); //false
System.out.println(s3.equals(s4)); //true
//没有重写类中的==与equals类型的比较 就是没有在父类中重写equals方法的类
People p1 = new People();
People p2 = new People();
System.out.println(p1.equals(p2)); //false
People p = p2;
System.out.println(p.equals(p2)); //true
}
解释:
-
针对第一种的基本类型的比较,正常比较其值即可。
-
针对String类型的比较,这里展开说明一下,因为String类对equals()方法进行了重写。
首先创建字符串对象通常有以下两种写法:
String s1 = "hello"; String s2 = new String("world");
第一种的话在字符串常量池中创建对象,并将对象引用赋值给s1;
第二种的话通过new关键字在堆中创建对象,并将对象引用赋值给s2.
字符串作为最基础的数据类型,使用非常频繁,如果每次都通过 new 关键字进行创建,会耗费高昂的时间和空间代价。Java 虚拟机为了提高性能和减少内存开销,就设计了字符串常量池. 在JDK1.7之前字符串常量池是存储在方法区的。JDK1.7之后存储在堆中了。
String类对equals的重写如下:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; 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; i++; } return true; } } return false; }
此外StringBuffer和StringBuilder并没有重写equals方法,其比较的还是引用类型的地址。
补充知识-Java中的8种基本数据类型
- 整数型
- byte(1字节)
- short(2字节)
- int(4字节)
- long(8字节)
- 浮点型
- float(4字节)
- double(8字节)
- 字符型
- char(2字节)
- 布尔型
- boolean(JVM没有明确规定其大小,仅规定其只能取true和false)