包装类:基本数据类型对应的类
一.什么是装箱?什么是拆箱?
装箱就是 自动将基本数据类型转换为包装器类型;拆箱就是 自动将包装器类型转换为基本数据类型。
Integer i = 10; //装箱 int n = i; //拆箱
下表是基本数据类型对应的包装器类型:
int 4 Integer
byte 1 Byte
short 2 Short
long 8 Long
float 4 Float
double 8 Double
char 2 Character
boolean 未定 Boolean
二.装箱和拆箱是如何实现的
在装箱的时候自动调用的是Integer的valueOf(int)方法
拆箱的时候自动调用的是Integer的intValue方法。
三.面试中相关的问题
public class Test { public static void main(String[] args) { Integer int1 = Integer.valueOf("100"); Integer int2 = Integer.valueOf("100"); System.out.println(int1 == int2); } }
源码:
public static Integer valueOf(String s) throws NumberFormatException { return Integer.valueOf(parseInt(s, 10)); } public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
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(可调)的整数都提前实例化了
但是为什么JDK要这么多此一举呢? 我们仔细想想, 淘宝的商品大多数都是100以内的价格, 一天后台服务器会new多少个这个的Integer, 用了IntegerCache,就减少了new的时间也就提升了效率。同时JDK还提供cache中high值得可配置,
这无疑提高了灵活性,方便对JVM进行优化。
Long源码也有cache:
private static class LongCache { private LongCache(){} static final Long cache[] = new Long[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); } }
只是没有调整机制
Boolean类
public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE); }
TRUE 和FALSE为Boolean中定义了2个静态成员属性
以下程序输出?
public static void main(String[] args) { Integer a = 1; Integer b = 2; Integer c = 3; Integer d = 3; Integer e = 321; Integer f = 321; Integer m = 322; Long g = 3L; Long h = 2L; System.out.println(c==d); System.out.println(e==f); System.out.println(c==(a+b)); System.out.println(c.equals(a+b)); System.out.println(g==(a+b)); System.out.println(g.equals(a+b)); System.out.println(g.equals(a+h)); System.out.println(m==(f+a)); }
对于包装器类型,equals方法并不会进行类型转换
true false true true true false true true
自动拆箱:
public static void main(String[] args) { int a = 10; Integer b = new Integer(10); System.out.println(a == b);//这里实际上是:a == b.intValue() }
true
以下代码?
public class Main { public static void main(String[] args) { Double i1 = 100.0; Double i2 = 100.0; Double i3 = 200.0; Double i4 = 200.0; System.out.println(i1==i2); System.out.println(i3==i4); } }
输出均为false
public static Double valueOf(String s) throws NumberFormatException { return new Double(FloatingDecimal.readJavaFormatString(s).doubleValue()); }
在这里只解释一下为什么Double类的valueOf方法会采用与Integer类的valueOf方法不同的实现。很简单:在某个范围内的整型数值的个数是有限的,而浮点数却不是。
注意,Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
Double、Float的valueOf方法的实现是类似的。
参考:http://www.cnblogs.com/dolphin0520/p/3780005.html
https://www.cnblogs.com/wellmaxwang/p/4422855.html