java中的包装类与装箱拆箱

来源:互联网 发布:网络市场发展趋势 编辑:程序博客网 时间:2024/05/22 12:51

1:Java有八种基本数据类型,对应八种包装类:

short Short

int Integer

long Long

char Character

byte Byte

float Float

boolean Boolean

double Double

变量的值存储在栈里,而对象存储在堆里,相比而言,堆栈更高效,这也是java保留基本类型的原因。包装类创建的对象,可以使用api提供的一些有用的方法。更为强大。

2、自动装箱与自动拆箱

那我们来分析Integer i = 5;

在jdk1.5以前,这样的代码是错误的,必须要通过Integer i = new Integer(5);这样的语句实现;而在jdk1.5以后,Java提供了自动装箱的功能,只需Integer i = 5;这样的语句就能实现基本数据类型传给其包装类,JVM为我们执行了Integer i = Integer.valueOf(5);这就是Java的自动装箱。

相对应的,把基本数据从对应包装类中取出的过程就是拆箱;如

Integer i = 5;

int j = i;//这样的过程就是自动拆箱

源码方面,用一句话总结装箱和拆箱的实现过程:

装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 xxxValue方法实现的。(xxx代表对应的基本数据类型)

Integer i = new Integer(xxx)和Integer i =xxx;这两种方式的区别:
1)第一种方式不会触发自动装箱的过程;而第二种方式会触发;
2)在执行效率和资源占用上的区别。第二种方式的执行效率和资源占用在一般性情况下要优于第一种情况(注意这并不是绝对的)。

在jdk1.5以前,这样的代码是错误的,必须要通过Integer i = new Integer(5);这样的语句实现;而在jdk1.5以后,Java提供了自动装箱的功能,只需Integer i = 5;这样的语句就能实现基本数据类型传给其包装类,JVM为我们执行了Integer i = Integer.valueOf(5);这就是Java的自动装箱。

相对应的,把基本数据从对应包装类中取出的过程就是拆箱;如

Integer i = 5;

int j = i;//这样的过程就是自动拆箱

缓存问题

public class Main {      public static void main(String[] args) {                     Boolean i1 = false;          Boolean i2 = false;          Boolean i3 = true;          Boolean i4 = true;                     System.out.println(i1==i2);          System.out.println(i3==i4);      }  } 
结果 

true

false

出现这样结果的原因可由源码解释,关于包装类有个边界的思想-128,127

    public static Integer valueOf(int i) {          if(i >= -128 && i <= IntegerCache.high)  // 没有设置的话,IngegerCache.high 默认是127              return IntegerCache.cache[i + 128];          else              return new Integer(i);      }  
而其中IntegerCache类的实现为:
private static class IntegerCache {          static final int high;          static final Integer cache[];            static {              final int low = -128;                // high value may be configured by property              int h = 127;              if (integerCacheHighPropValue != null) {                  // Use Long.decode here to avoid invoking methods that                  // require Integer's autoboxing cache to be initialized                  int i = Long.decode(integerCacheHighPropValue).intValue();                  i = Math.max(i, 127);                  // Maximum array size is Integer.MAX_VALUE                  h = Math.min(i, Integer.MAX_VALUE - -low);              }              high = h;                cache = new Integer[(high - low) + 1];              int j = low;              for(int k = 0; k < cache.length; k++)                  cache[k] = new Integer(j++);          }            private IntegerCache() {}      } 

从这2段代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。
  上面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。

以下还有Double boolean  自己看源码去吧.......





原创粉丝点击