1.==
(1)作用于基本数据类型:直接对其值进行比较;
(2)作用于引用类型:判断引用是否指向堆内存中的同一块地址 ;
2.equals
- equals 与 == 不同,它是一个方法,而方法又存在于某一个类中;所有类都继承于Object类,我们先看一下Object类中的equals()方法:
public boolean equals(Object obj) {
return (this == obj);
}
由此可见:Object类中的equals()方法是直接使用了 == ,故:若没有对Object类中的equals()方法进行覆写,则 equals 与 == 等效,比较的是引用类型的变量所指向的对象的地址,反之则比较的是内容;
-
没有重写equals()方法的类(包括自己写的类),equals 与 == 等效;
-
像String、Integer等类,对equals()方法进行了覆写,在使用的时候如果不清楚我们可以去源码查看一下是如何覆写的,例:String类,直观的讲就是比较所有字符是不是都相同;
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;
}
- equals()方法不能作用于基本数据类型的变量,因为基本数据类型非对象,没有方法;
3. equals 和 == 的区别:
- 定义不同:
Java中,equals是一个方法,== 是一个运算符 - 运行速度不同:
== 比 equals 运行速度快,因为 == 只是比较引用 - 比较的东西不同:
== :判断是否指向同一块内存空间,即:引用是否相同;
equals :判断所指向的内存空间的值是否相同,即:值是否相同;
4.代码分析:
(1)String类:
public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
String s4 = new String("hello");
// 运行结果
System.out.println(s1==s2); // true
System.out.println(s1.equals(s2)); // true
System.out.println(s3==s4); // false
System.out.println(s3.equals(s4)); // true
System.out.println(s1==s3); // false
System.out.println(s1.equals(s3)); // true
}
在String类中:
-
String s1 = "hello";
为直接量,存在于常量池中
当以这样的方式声明一个字符串时,会先在常量池中寻找有没有一个值为hello
的对象;若有,则把它赋给当前引用;若没有,则:先在常量池中新创建一个值为hello
的对象,再将其赋给当前引用;
以这种方式声明的字符串,只要值相等,则:引用都指向同一对象; -
String s3 = new String("hello");
:不管内存中是否有这个对象,都会新建一个对象; -
s1==s2
:s1、s2两个引用都指向常量池中同一对象,故为 true; -
s3、s4 虽然值都相同,但在堆中为两个不同的对象,故:
s3==s4
为false;s3.equals(s4)
为true;
- 图解:
(2)Integer类:
public static void main(String[] args) {
int a = 6;
int b = 6;
Integer a1 = 50;
Integer a2 = 50;
Integer a3 = 500;
Integer a4 = 500;
// 运行结果
System.out.println(a==b); // true
System.out.println(a1==a2); // true
System.out.println(a1.equals(a2)); // true
System.out.println(a3==a4); // false
System.out.println(a3.equals(a4)); // true
}
a1==a2
为true,而 a3==a4
却为false,这是为什么呢?
让我们去看看源码:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
原来,在定义一个Integer类型的变量时,会进行 Integer.valueOf(int i)
操作;
对于 Integer a = num;
的值 num 在 [-128,127] 之间时,Integer对象是在 IntegerCache.cache 产生,会复用已有对象;但是,若值在这个区间之外,都会在堆上产生,并不会复用已有对象;
- 图解:
我太懒了,就在上个图基础上改了改,哈哈(^_^)