美文网首页
Java包装类--自动拆箱装箱

Java包装类--自动拆箱装箱

作者: otmoc | 来源:发表于2018-10-17 18:40 被阅读0次
    1、 什么是包装类

    包装类就是Java基本数据类型的对象表示形式。其中包括基本数据类型byte, char, short, int, long, float, double, boolean。

    2、有哪些包装类
    • byte <====> java.lang.Byte
    • char <====> java.lang.Character
    • short <====> java.lang.Short
    • int <====> java.lang.Integer
    • long <====> java.lang.Long
    • float <====> java.lang.Float
    • double <====> java.lang.Double
    • boolean <====> java.lang.Boolean
    3、为什么要用包装类
    1. Java是一门面向对象语言,在进行面向对象开发时,有些方法声明必须传入对象,而基本类型值不具备对象特性,为了基本类型具有对象特征,这时就出现了包装类
    2. 泛型不能使用基本类型,例如List<T>, Set<T>, Map<K, V>
    4、使用包装类有哪些值得注意的地方
    • byte <====> java.lang.Byte

      private static class ByteCache {
          private ByteCache(){}
      
          // byte 占一个字节8bit,有符号,取值范围 -2^7 ~ 2^7-1
          static final Byte cache[] = new Byte[-(-128) + 127 + 1];
      
          static {
              // 初始化Byte缓存
              for(int i = 0; i < cache.length; i++)
                  cache[i] = new Byte((byte)(i - 128));
          }
      }
      
      public static Byte valueOf(byte b) {
          final int offset = 128;
          return ByteCache.cache[(int)b + offset];
      }
      

      无论short取何值, 都从缓存中的获取。即

      Byte a = 1;
      Byte b = 1;
      System.out.println(a == b);
      // print true
      
    • char <====> java.lang.Character

      private static class CharacterCache {
          private CharacterCache(){}
      
          static final Character cache[] = new Character[127 + 1];
      
          static {
              // 缓存标准ASCII表
              for (int i = 0; i < cache.length; i++)
                  cache[i] = new Character((char)i);
          }
      }
      
      public static Character valueOf(char c) {
          if (c <= 127) { // must cache
              return CharacterCache.cache[(int)c];
          }
          return new Character(c);
      }
      

      当char取值在0~127范围内,取缓存中的,不在次范围内的在java堆中创建新对象。即

      Character a = 'a';
      Character b = 'a';
      System.out.println(a == b);
      // print trueni
      
      Character c = '你';
      Character d = '你';
      System.out.println(c == d);
      // print false
      
    • short <====> java.lang.Short

      private static class ShortCache {
          private ShortCache(){}
      
          static final Short cache[] = new Short[-(-128) + 127 + 1];
      
          static {
              for(int i = 0; i < cache.length; i++)
                  cache[i] = new Short((short)(i - 128));
          }
      }
      
      public static Short valueOf(short s) {
          final int offset = 128;
          int sAsInt = s;
          if (sAsInt >= -128 && sAsInt <= 127) { // must cache
              return ShortCache.cache[sAsInt + offset];
          }
          return new Short(s);
      }
      

      当short取值在-128~127范围内,取缓存中的,不在次范围内的在java堆中创建新对象。即

      Short a = 1;
      Short b = 1;
      System.out.println(a == b);
      // print true
      
      Short c = 256;
      Short d = 256;
      System.out.println(c == d);
      // print false
      
    • int <====> java.lang.Integer

      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() {}
      }
      
      public static Integer valueOf(int i) {
          if (i >= IntegerCache.low && i <= IntegerCache.high)
              return IntegerCache.cache[i + (-IntegerCache.low)];
          return new Integer(i);
      }
      

      默认,当integer取值-128~127范围内时,去缓存中的,不在此范围内的在java堆中创建新对象。
      Integer最大范围可以通过设置参数java.lang.Integer.IntegerCache.high改变

      Integer a = 1;
      Integer b = 1;
      System.out.println(a == b);
      // print true
      
      Integer c = 256;
      Integer d = 256;
      System.out.println(c == d);
      // print false
      java -Djava.lang.Integer.IntegerCache.high=256
      // print true
      
    • long <====> java.lang.Long

      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 - 1shi28);
          }
      }
      
      public static Long valueOf(long l) {
          final int offset = 128;
          if (l >= -128 && l <= 127) { // will cache
              return LongCache.cache[(int)l + offset];
          }
          return new Long(l);
      }
      

      默认,当integer取值-128~127范围内时,去缓存中的,不在此范围内的在java堆中创建新对象。

      Long a = 1L;
      Long b = 1L;
      System.out.println(a == b);
      // print true
      
      Long c = 256L;
      Long d = 256L;
      System.out.println(c == d);
      // print false
      
    • float <====> java.lang.Float

      public static Float valueOf(float f) {
          return new Float(f);
      }
      

      无论float什么取值都从java堆中新建对象,即

      shiFloat a = 1.0f;
      Float b = 1.0f;
      System.out.println(a == b);
      // print false
      
    • double <====> java.lang.Double

      public static Double valueOf(double d) {
          return new Double(d);
      }
      

      无论double什么取值都从java堆中新建对象,即

      Double a = 1.0;
      Double b = 1.0;
      System.out.println(a == b);
      // print false
      

      为什么float和double都不缓存值?---->因为float,dobule都是精度值,区间内存在无限可取值,缓存无意义

    • boolean <====> java.lang.Boolean

      Integer a = Integer.valueOf(1);public static Boolean valueOf(boolean b) {
          return (b ? TRUE : FALSE);
      }
      

      boolean 只有两种取值选择,即true or false; 则他们取值总是相等。

      当对象直接通过new创建,将不会发生装箱,直接在java堆中创建。

    5、什么情况发生自动拆箱装箱
    1. 赋值

      Integer a = 1;
      int b = a;
      
      //编译后按照以下执行
      Integer a = Integer.valueOf(1);
      int b = a.intValue();
      
    2. 运算

      Integer a = 1;
      Integer b = 1;
      Integer c = a+b;
      
      //编译后按照以下执行
      Integer a = Integer.valueOf(1);
      Integer b = Integer.valueOf(1);
      Integer c = Integer.valueOf(a.intValue() + b.intValue());
      
    3. 比较

      Integer a = 1;
      int b = 2;
      System.out.println(a == b);
      
      //编译后按照以下执行
      Integer a = Integer.valueOf(1);
      int b = 2;
      System.out.println(a.intValue() == b);
      

      注意同是Integer类型之间的比较不会拆箱

    4. 方法调用

      Integer a = 1;
      System.out.println(a.compareTo(2));
      
      //编译后按照以下执行
      Integer a = Integer.valueOf(1);
      System.out.println(a.compareTo(Integer.valueOf(2)));
      
    6、包装类继承结构
    以上如有错误和不足的地方,请谅解和批评指正,不胜感激!
    请尊重作者成果,转载时请标注原文: https://www.jianshu.com/p/bbfc9675d63d

    相关文章

      网友评论

          本文标题:Java包装类--自动拆箱装箱

          本文链接:https://www.haomeiwen.com/subject/xugrzftx.html