1、== 与 equals
“==”:
- “==” 是属于关系运算符,返回一个 boolean 类型的值。
- 对于基本数据类型的比较,是直接比较值的大小。
- 对于引用数据类型的比较,则对对象地址进行比较。
equals:
- equals 是属于 Object 的一个方法。
- 类没有覆盖 equals 方法时,会使用 Object 类的 equals 方法,因为 Object 类中的 equals 方法是直接 使用 “==” 运算符比较,所以没有覆盖 equals 情况下 “==” 与 equals 是一样的。
- 类覆盖 equals 方法时,比较规则一般用于对象内容的比较,如果相等则两个对象相等。
Object 中 equals 方法源码:
public boolean equals(Object obj) {
return (this == obj);
}
2、String类型的比较
例1:
String s1 = "张三";
String s2 = new String("张三");
System.out.println(s1 == s2); //false
System.out.println(s1.equals(s2)); //true
字符串直接赋值与使用 new 创建字符串实例进行比较
使用 “==” 比较地址,s1直接引用常量池中的对象,s2引用堆内存中创建的字符串实例,地址不同,所以结果为 false。
使用 equals 方法会比较对象的值,结果为 true。
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;
}
3、基本数据类型与包装类直接的比较(以 int 与 Integer 为例)
例1:
Integer integer1 = new Integer(10);
Integer integer2 = new Integer(10);
System.out.println(integer1 == integer2); //false
System.out.println(integer1.equals(integer2)); //true
通过 new 关键字创建两个 Integer 实例进行比较
使用 “==” 比较地址,结果为 false。
使用 equals 方法比较,根据 Integer 中的 equals 方法比较规则,会进行拆箱成 int 类型,然后与equals 调用者的 value 进行比较,所以本质上是 int 类型的比较,结果为true。
Integer中equals方法源码:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
例2:
int i = 10;
System.out.println(integer1 == i); //true
System.out.println(integer1.equals(i)); //true
通过 Integer 对象与 int 类型比较
使用 “==” 比较,Integer类型(包括new创建和直接赋值) 遇到 int 类型时 Integer 会自动拆箱,所以本质上是两个int类型比较,结果为true。
使用 equals 比较,如果 equals 方法传入的是 int 类型,则会进行自动装箱成Integer类型进行比较。
关于 Integer 中 equals 方法传入 int 类型:equals 方法接收一个 Object 类型的参数,如果传入的是 int 类型,则会自动装箱成 Integer 类型。
代码示例:
Object o = 10; //Object类型接收一个int类型数据
System.out.println(o.getClass());
运行结果:
class java.lang.Integer
例3:
Integer i1 = 128;
Integer i2 = 128;
Integer i3 = 127;
Integer i4 = 127;
System.out.println(i1 == i2); //false
System.out.println(i3 == i4); //true
System.out.println(i1.equals(i2)); //true
System.out.println(i3.equals(i4)); //true
//Integer i1 = 128; 可以写成:Integer i1 = Integer.valueOf(128);
定义 Integer 类型接收 int 类型数据。
给 Integer 类型直接赋值 int 类型会自动装箱成 integer 类,在装箱过程中,如果值在[-128,127]范围内,则会直接返回 IntegerCache.cache 中缓存的对象,如果不在这个范围则会用过 new 关键字创建一个新的 Integer 对象。
所以,上述比较中
使用 “==” 比较,如果值在 [-128,127] 之间比较结果为 true,反之为 false。
使用 equals 比较会比较存储的值,结果为 true。
Integer 类 valueof 方法源码:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
IntegerCache 源码:
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {
}
}
——THE END——