最近市场行情不太好,为了让自己保值,打算从基础开始重新学一遍java相关的知识。
今天先从最简单的Integer说起,Integer实际上是int的封装类,因为在java的世界里,万物皆对象,即便是基础数据类型,实际上在背后都会有对应的封装类。
当我们写Integer a=new Integer(100);时实际上就是纯粹的创建了一个Integer对象。
当我们写Integer a=100;时,实际上由于java语法糖的存在,编译器会将这行代码翻译成Integer a=Integer.valueOf(100);我们再来看Integer.valueOf(int i)方法:
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() {}
}
通过以上代码,我们可以很清楚的知道在Integer内部存在一个缓存,这个缓存会默认保存-128~127个Integer对象,而且这些对象的创建写在了static块中,意味着很早就被创建出来了。一旦我们执行Integer a=x(-128<=x<=127,实际上返回的都是同一个IntegerCache中缓存的对象。只有当x>127或x<-128时,才相当于new了一个新对象。
看到这里我们就需要掌握一个技巧了:
能用a=100就不要用a=new Integer(100),以达到利用Integer缓存的机制。
Integer类还有个需要看的地方是他重写了equals方法:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
很清晰的可以看到,Integer之间的equals比较实际上就是”值“比较,只需要看两个数一不一样就好了。那有人会问,int属于Integer嘛?当然,int在底层会被自动转成Integer,还记得那句话么?万物皆对象。
通过以上的了解,大家可以试着做一下下面这些题:
//第1题
int a=100;
Integer b=100;
System.out.print(a==b);
答案:true
解释:当一个Integer对象和基本数据类类型int相比较的时候,虚拟机会将Integer对象自动拆包成int,这个时候通过==进行比较的就是”值“了。
//第2题
int a=100;
Integer b=new Integer(100);
System.out.print(a==b);
答案:true
解释:与第一题一样,无论这个Integer对象是通过语法糖创建的,还是通过new对象创建的。其本质都已经是Integer对象了。只要是Integer对象,在和int进行==比较时,就都是”值“比较。
//第3题
Integer a=100;
Integer b=100;
System.out.print(a==b);
答案:true
解释:两个都是对象,但由于-128<100<127,所以实际上都是去的IntegerCache中的同一个对象,当两个对象进行==比较时,实际上是比较的内存地址,因为只是同一个对象的两个不同引用,所以内存地址实际相等。
//第4题
Integer a=130;
Integer b=130;
System.out.print(a==b);
答案:false
解释:IntegerCache只缓存-128-127之间的数对象。对于不在其范围内的对象都相当于创建了一个新对象。(除非动了虚拟机参数,将IntegerCache的缓存范围修改了。)
//第5题
int a=130;
Integer b=130;
Integer c=130;
Integer d=new Integer(130);
System.out.print(b.equal(a)&&b.equals(c)&&b.equals(d)&&c.equals(d));
答案:true
解释:integer重写了equals方法,将判断改成了值判断,值相等则equals方法一定为true。
网友评论