1.为阅读体验,本站无任何广告,也无任何盈利方法,站长一直在用爱发电,现濒临倒闭,希望有能力的同学能帮忙分担服务器成本
2.捐助10元及以上同学,可添加站长微信lurenzhang888,备注捐助,网站倒闭后可联系站长领取本站pdf内容
3.若网站能存活下来,后续将会持续更新内容
Java的自动装箱:将基本类型用包装器类型包装起来
Java的自动拆箱:将包装器类型转换为基本类型
这个地方有很多易混淆的地方,但在面试中问到的频率一般,笔试的选择题中经常出现,还有一个
String
创建对象和这个比较像,很容易混淆,在下文可以看到
- 下面这段代码的输出结果是什么?
public class Main {
public static void main(String[] args) {
Integer a = 100;
Integer b = 100;
Integer c = 128;
Integer d = 128;
System.out.println(a==b);
System.out.println(c==d);
}
}
true
false
很多人看到这个结果会很疑惑,为什么会是一个true
一个flase
.其实从源码中可以很容易找到原因.首先找到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);
}
可以看到当不满足if
语句中的条件,就会重新创建一个对象返回,那结果必然不相等。继续打开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() {}
}
代码挺长,大概说的就是在通过valueOf
方法创建Integer
对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache
中已经存在的对象的引用;否则创建一个新的Integer
对象。所以上面代码中a
与b
相等,c
与d
不相等。
- 在看下面的代码会输出什么
public class Main {
public static void main(String[] args) {
Double a = 1.0;
Double b = 1.0;
Double c = 2.0;
Double d = 2.0;
System.out.println(a==b);
System.out.println(c==d);
}
}
flase
flase
采用同样的方法,可以看到Double
的valueOf
方法,每次返回都是重新new
一个新的对象,所以上面代码中的结果都不想等。
public static Double valueOf(double d) {
return new Double(d);
}
- 最后再看这段代码的输出结果
public class Main {
public static void main(String[] args) {
Boolean a = false;
Boolean b = false;
Boolean c = true;
Boolean d = true;
System.out.println(a==b);
System.out.println(c==d);
}
}
true
true
老方法继续看valueOf
方法
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
再看看TRUE
和FALSE
是个什么东西,是两个静态成员属性。
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
说下结论 :Integer
、Short
、Byte
、Character
、Long
这几个类的valueOf
方法的实现是类似的。Double
、Float
的valueOf
方法的实现是类似的。然后是Boolean
的valueOf
方法是单独一组的。
Integer i = new Integer(xxx)
和Integer i =xxx
的区别
这两者的区别主要是第一种会触发自动装箱,第二者不会
最后看看下面这段程序的输出结果
public class Main {
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer c = 3;
Long g = 3L;
int int1 = 12;
int int2 = 12;
Integer integer1 = new Integer(12);
Integer integer2 = new Integer(12);
Integer integer3 = new Integer(1);
System.out.println("c==(a+b) ->"+ (c==(a+b)));
System.out.println("g==(a+b) ->" + (g==(a+b)));
System.out.println( "c.equals(a+b) ->" + (c.equals(a+b)));
System.out.println( "g.equals(a+b) ->" + (g.equals(a+b)));
System.out.println("int1 == int2 -> " + (int1 == int2));
System.out.println("int1 == integer1 -> " + (int1 == integer1));
System.out.println("integer1 == integer2 -> " + (integer1 == integer2));
System.out.println("integer3 == a1 -> " + (integer3 == a));
}
}
c==(a+b) ->true
g==(a+b) ->true
c.equals(a+b) ->true
g.equals(a+b) ->false
int1 == int2 -> true
int1 == integer1 -> true
integer1 == integer2 -> false
integer3 == a1 -> false
下面简单解释这些结果。
1.当 “==”运算符的两个操作数都是包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。所以c==a+b
,g==a+b
为true
。
2.而对于equals
方法会先触发自动拆箱过程,再触发自动装箱过程。也就是说a+b,会先各自调用intValue
方法,得到了加法运算后的数值之后,便调用Integer.valueOf
方法,再进行equals
比较。所以c.equals(a+b)
为true
。而对于g.equals(a+b)
,a+b
会先拆箱进行相加运算,在装箱进行equals
比较,但是装箱后为Integer
,g
为Long
,所以g.equals(a+b)
为false
。
3.int1 == int2
为true
无需解释,int1 == integer1
,在进行比较时,integer1
会先进行一个拆箱操作变成int
型在进行比较,所以int1 == integer1
为true
。
4.integer1 == integer2
->false
。integer1
和integer2
都是通过new
关键字创建的,可以看成两个对象,所以integer1 == integer2
为false
。integer3 == a1
-> false
, integer3
是一个对象类型,而a1
是一个常量它们存放内存的位置不一样,所以integer3 == a1
为false
,具体原因可学习下java的内存模型。
本站链接:https://www.mianshi.online,如需勘误或投稿,请联系微信:lurenzhang888
点击面试手册,获取本站面试手册PDF完整版