java自动装箱拆箱浅析
jopen
9年前
自动装箱拆箱概念
在Java SE 5之后,为基本数据类型提供了自动装箱和拆箱功能,使得将基本类型转换与对象之间的转换变得极其便捷。 | 基本数据类型 | 包装类 | | int(4字节) | Integer | | byte(1字节) | Byte | | short(2字节) | Short | | long(8字节) | Long | | float(4字节) | Float | | double (8字节) | Double | | char(2字节) | Character | | boolean(未定) | Boolean | Integer i = 100;(拆箱) int j = i;(装箱)
自动装箱拆箱的实现
Integer i = 100;(拆箱) int j = i;(装箱) //上面两行代码的反编译如下: Integer i = Integer.valueOf(100);//拆箱 int j = i.intValue();//装箱 对于其他基本类型的装箱和拆箱和int类似。
案例分析
Integer
(1)案例 int a = 100; int b = 100; System.out.println(a == b); int c = 200; int d = 200; System.out.println(c == d); Integer e = new Integer(100); System.out.println(a == e); //结果 true true true //反编译 byte a = 100; byte b = 100; System.out.println(a == b); short c = 200; short d = 200; System.out.println(c == d); Integer e = new Integer(100); System.out.println(a == e.intValue()); 如果改为下面的代码呢? (2)案例 Integer a = 100; Integer b = 100; System.out.println(a == b); //int c = 200; Integer c = 200; Integer d = 200; System.out.println(c == d);//输出true Integer e = new Integer(100); System.out.println(a == e); //结果 true false false //反编译结果 Integer a = Integer.valueOf(100); Integer b = Integer.valueOf(100); System.out.println(a == b); Integer c = Integer.valueOf(200); Integer d = Integer.valueOf(200); System.out.println(c == d); Integer e = new Integer(100); System.out.println(a == e);
(1)案例和(2)案例为啥不一样呢?
当 "=="运算符的两个操作数都是包装器类型的引用,则比较的是对象;而如果其中有一个操作数是表达式(即包含算术运算)或是基本类型则比较的是数值。
原因分析:我们查看一下valueOf()源码
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) //这里有个IntegerCache return IntegerCache.cache[i + (-IntegerCache.low)]; //当大于high小于low时才新建 return new Integer(i); } //可以得知low=-128,high=127 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() {} }
Boolean
boolean a = true; boolean b = true; System.out.println(a == b); Boolean c = true; Boolean d = true; System.out.println(c == d); //结果 true true //反编译 boolean a = true; boolean b = true; System.out.println(a == b); Boolean c = Boolean.valueOf(true); Boolean d = Boolean.valueOf(true); System.out.println(c == d);
为什么是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);
Double
double a = 1.0; double b = 1.0; System.out.println(a == b); Double c = 1.0; Double d = 1.0; System.out.println(c == d); //结果 true false //反编译 double a = 1.0D; double b = 1.0D; System.out.println(a == b); Double c = Double.valueOf(1.0D); Double d = Double.valueOf(1.0D); System.out.println(c == d); //valueOf()源码 public static Double valueOf(double d) {//创建了新对象 return new Double(d); }
Long
Integer a = 1; Integer b = 2; Integer c = 3; Integer d = 3; Integer e = 321; Integer f = 321; Long g = 3L; Long h = 2L; System.out.println(c==d);//-127~128 System.out.println(e==f);//>128 System.out.println(c==(a+b));//自动拆箱 System.out.println(c.equals(a+b));//都是Integer类型 System.out.println(g==(a+b));//自动拆箱,向上转型为long System.out.println(g.equals(a+b));//类型不匹配 System.out.println(g.equals(a+h));//向上转型为Long //结果 true false true true true false true //反编译 Integer a = Integer.valueOf(1); Integer b = Integer.valueOf(2); Integer c = Integer.valueOf(3); Integer d = Integer.valueOf(3); Integer e = Integer.valueOf(321); Integer f = Integer.valueOf(321); Long g = Long.valueOf(3L); Long h = Long.valueOf(2L); System.out.println(c == d); System.out.println(e == f); System.out.println(c.intValue() == a.intValue() + b.intValue()); System.out.println(c.equals(Integer.valueOf(a.intValue() + b.intValue()))); System.out.println(g.longValue() == (long)(a.intValue() + b.intValue())); System.out.println(g.equals(Integer.valueOf(a.intValue() + b.intValue()))); System.out.println(g.equals(Long.valueOf((long)a.intValue() + h.longValue()))); //Long的equals public boolean equals(Object obj) { if (obj instanceof Long) {//类型不一样便是false return value == ((Long)obj).longValue(); } return false; }