java自动装箱拆箱浅析

jopen 8年前

自动装箱拆箱概念

在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;  }



来自: http://my.oschina.net/u/2361475/blog/599242