==和equals()
双等号是java的比较符,作用如下:
- 基本类型跟基本类型比较,比较的是数值是否相等
- 引用类型跟引用类型比较,比较的是引用是否相等(即是否同一个对象)
- 其他情况:
//src指向了常量池的字面量“cc” String src = "cc"; //s指向的是String对象,该对象再指向“cc” String s = new String("cc") System.out.println(src == "cc");//true System.out.println(s == "cc");//false int a = 666; //其他创建方式也一样 Integer b = new Integer(666); //自动拆箱 System.out.println(a==b);//true
上述描述大体上是没问题的,但如果你学习过java的内存模型,就会有更深入的认识!
equals()方法,如果使用默认的(继承自Object类),那它用的就是双等号,用来比较引用是否相等!
//obj不仅可以是引用类型,也可以是int类型/数字/字面量,只不过没有意义
public boolean equals(Object obj) {
return (this == obj);
}
但一般equals()方法都会被重写,比如String重写后的equals()方法,比较的就是字符串的内容是否相等。
public boolean equals(Object anObject) {
//跟本身比较,直接返回true
if (this == anObject) {
return true;
}
//当且仅当字符串长度相等,且每个字符对应相等,返回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;
}
包装类Integer也重写了equals()方法。作用跟上面类似,比较的整数值是否相等!
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
无论你通过哪种方式创建的Integer,无论你传进去的是Integer对象还是int类型,只要整数值相等,那equals()方法就返回true。
int a = 133;
Integer b = 133;
Integer c = new Integer(133);
System.out.println(c.equals(a));//true
System.out.println(b.equals(a));//true
System.out.println(c.equals(b));//true
Integer的equals()方法是比较整数值是否相等,不需要考虑各种情况,比较简单。
但使用双等号就不一样了,不是说数值相等就返回true。有各种各样的情况,有些情况是比较整数值,有些情况是比较引用。如果想要了解得更透彻就需要翻一下源码。
Integer创建方式
我们创建Integer对象时,一般都会传进一个value。这里只讨论3种创建方式。
- 直接new:直接返回Integer对象
- 直接赋值:返回缓存值或Integer对象
//返回缓存值 Integer integer1 = 127; //new一个Integer返回 Integer integer2 = 128;
- 调用静态方法valueOf():返回缓存值或Integer对象
//入参int,若在缓存值范围则返回缓存值,否则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); } //入参String,调用parseInt()方法将String转为int public static Integer valueOf(String s) throws NumberFormatException { return Integer.valueOf(parseInt(s, 10)); }
可以看到,直接赋值和调用静态方法,这种非new的Integer涉及到了缓存值这个概念,那么缓存值指的是什么呢?
这其实跟Integer的底层有关,Integer类里有一个私有静态内部类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() {}
}
这个IntegerCache有什么用呢?简单来说,它开辟了一个数池(具体存储方式是数组),里面存放了-127至128范围的整数。当输入的值(value)在这个数值范围内,返回的是缓存数组中的值;若超过数值范围,则new一个Integer对象返回。
知道这个,你就能很好地理解下面的各种情况了。
Integer使用==详解
int int1 = 128;
//以下是创建了Integer对象
Integer integer1 = 128;
Integer integer1a = 128;
Integer integer2 = new Integer(128);
Integer integer3 = Integer.valueOf(128);
Integer integer4 = Integer.valueOf("128");
//以下是返回了数池中的缓存值
Integer integer5 = 127;
Integer integer5a = 127;
Integer integer7 = Integer.valueOf(127);
//int跟Integer比较
System.out.println(int1 == integer1);//true
System.out.println(int1 == integer2);//true
System.out.println(int1 == integer3);//true
//Integer间比较
System.out.println(integer1 == integer2);//false
System.out.println(integer1 == integer3);//false
System.out.println(integer1 == integer1a);//false
System.out.println(integer5 == integer5a);//true
可以看出在数值相同的情况下:
int==任何一种方式创建的Integer,返回的都是true,这是由于Integer跟int比较时会自动拆箱为int类型,两个int类型比较的就是数值。关于Integer自动拆装箱的详细内容,这里推荐别人的一篇文章:http://t.csdn.cn/4Gyqw
Integer==Integer,则比较复杂,需要看是哪种方式创建的Integer,并且value是否在-128至127之间。
如果是new的Integer,返回的必定是对象,==是比较引用,一般返回false。
非new的Integer,value在-128至127之间,返回的是值,否则返回对象。
总结
在数值相等的情况下,==返回true还是false呢?
- int类型跟Integer(任何一种),返回true。
- Integer之间
- new与new:返回false
- new与非new:返回false
- 非new与非new
- -128至127之间:返回true
- 范围之外:返回false
对于Integer的比较来说,我们更多时候关注的是数值是否相同,这时候就不应该使用双等号来比较,而是使用equals()方法。
若有错误,恳请在评论区指正!欢迎大家友好交流!