Java自动拆装箱简单介绍

 更新时间:2017年10月11日 15:08:28   作者:夜孤寒  
这篇文章主要为大家详细介绍了Java自动拆装箱的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

在面试过程中,常常会有面试官问到基础的问题的时候都会问到Java的拆装箱,关于这个问题其实不是很难,但是如果平时进行自学的时候不是注意,就可能一脸懵逼,所以笔者就这个问题进行一些总结,共同促进!

一、拆装箱概念

所谓的拆装箱,就是自从JDK1.5之后,java的基本类型和引用类型之间的相互转换。

1.1拆箱

拆箱就是把Long,Integer,Double,Float 等将基本数据类型的首字母大写的相应的引用类型转化为基本数据类型的动作就叫拆箱。

1.2装箱

装箱就是把byte ,int ,short, long ,double,float,boolean,char 这些Java的基本数据类型在定义数据类型时不声明为相对应的引用类型,在编译器的处理下自动转化为引用类型的动作就叫做装箱。

二、拆装箱的相关应用

在JDK1.5后,当我们进行基本类型和引用类型的转换的时候就会方便:

package com.hzp.CZX;
/**
 * 测试拆装箱
 * @author 夜孤寒
 * @version 1.1.1
 */
public class TestDemo {
  /**
   * 拆装箱JDK1.5后
   */
  public static void first(){
    Integer i=7;//基本类型-->引用类型
    int j=i;//引用类型-->基本类型
    System.out.println(j);
  }
  /**
   * 拆装箱JDK1.4
   */
  public static void second(){
    Integer i=new Integer(78);
    int j=i.intValue();
    System.out.println(j);
  }
  /**
   * 测试方法
   * @param args
   */
  public static void main(String[] args) {
    first();
    second();
  }
}

上面介绍了关于拆装箱的一些基本点和使用方式,但是要使用拆装箱的话还有一些注意点需要注意,下面将这些注意点进行一些总结。

三、注意点

首先贴一段代码如下:

package com.ygh.CZX;
/**
 * 关于java的拆装箱范围剖析
 * @author 夜孤寒
 * @version 1.1.1
 */
public class Test {
  /**
   * 以Integer类型为例
   */
  public static void first(){
    Integer i=new Integer(124);
    Integer j=new Integer(124);
    System.out.println(i==j);//false
    Integer a1=-128;
    Integer a2=-128;
    System.out.println(a1==a2);//true
    Integer b1=-129;
    Integer b2=-129;
    System.out.println(b1==b2);//false
    Integer c1=127;
    Integer c2=127;
    System.out.println(c1==c2);//true
    Integer d1=128;
    Integer d2=128;
    System.out.println(d1==d2);//false
  }
  public static void main(String[] args) {
    first();
    
  }
}

简单解释一下:

第一个结果为false的原因是因为创建了不同的对象,所以两者不一样;

但是第二个和第三个的结果为什么不一样?

下面贴出关于Integer类的源码,从源码的角度来分析这个问题:

  /**
   * Returns an {@code Integer} instance representing the specified
   * {@code int} value. If a new {@code Integer} instance is not
   * required, this method should generally be used in preference to
   * the constructor {@link #Integer(int)}, as this method is likely
   * to yield significantly better space and time performance by
   * caching frequently requested values.
   *
   * This method will always cache values in the range -128 to 127,
   * inclusive, and may cache other values outside of this range.
   *
   * @param i an {@code int} value.
   * @return an {@code Integer} instance representing {@code i}.
   * @since 1.5
   */
  public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
      return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
  }

上面的代码是说,进行自动拆装箱的时候,是有一个范围的,一旦超出这个范围,那么指向的就不是同一个对象,而是返回一个新创建的对象了,这个范围在Integer类中的一个内部私有类IntegerCache可以体现出来,源码如下:

 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() {}
  }

从这里我们可以看出,范围值为[-128,127]之间。

注意,Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
Double、Float的valueOf方法的实现是类似的。

总结:这些进行自动拆装箱的基本类型的范围如下:

1. boolean类型的值

2.所有的byte的值

3.在-128~127的short类型的值

4.在-128~127的int类型的值

5.在\ u0000~\ u00ff 之间的char类型的值

而其中double和float又有所不同,我们就以double为例子,贴出代码讨论:

package com.ygh.CZX;

/**
 * 关于java的拆装箱范围剖析
 * 
 * @author 夜孤寒
 * @version 1.1.1
 */
public class Test {
  /**
   * Double
   */
  public static void first() {
    Double i1 = 100.0;
    Double i2 = 100.0;
    Double i3 = 200.0;
    Double i4 = 200.0;
    System.out.println(i1 == i2);//false
    System.out.println(i3 == i4);//false
  }
  /**
   * 测试方法
   */
  public static void main(String[] args) {
    first();
  }
}

注意为什么上面的代码的输出结果都是false呢?同样的我们依旧以Double类中的valueOf方法来讨论,贴出源码就一目了然了:

  /**
   * Returns a {@code Double} instance representing the specified
   * {@code double} value.
   * If a new {@code Double} instance is not required, this method
   * should generally be used in preference to the constructor
   * {@link #Double(double)}, as this method is likely to yield
   * significantly better space and time performance by caching
   * frequently requested values.
   *
   * @param d a double value.
   * @return a {@code Double} instance representing {@code d}.
   * @since 1.5
   */
  public static Double valueOf(double d) {
    return new Double(d);
  }

也就是说不管你的double是什么范围的值,他都是给你返回一个新的对象。float同double,就不过多赘述了。

以上就是笔者对于拆装箱的一些整理,如果读者有不同的看法可以在评论区提出,笔者再进行修改!

希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Netty中ChannelPoolHandler调用处理程序详解

    Netty中ChannelPoolHandler调用处理程序详解

    这篇文章主要介绍了Netty中ChannelPoolHandler调用处理程序详解,Netty 是基于 Java NIO 的异步事件驱动的网络应用框架,使用 Netty 可以快速开发网络应用,Netty 提供了高层次的抽象来简化 TCP 和 UDP 服务器的编程,但是你仍然可以使用底层的 API,需要的朋友可以参考下
    2023-11-11
  • Java POI读取excel中数值精度损失问题解决

    Java POI读取excel中数值精度损失问题解决

    这篇文章主要介绍了Java POI读取excel中数值精度损失问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Java中String的intern()方法详细说明

    Java中String的intern()方法详细说明

    这篇文章主要介绍了Java中String的intern()方法详细说明,String::intern()是一个本地方法,他的作用就是如果字符串常量池中已经包含了一个等于此String对象的字符串,则返回代表池中的这个字符串额String对象的引用,需要的朋友可以参考下
    2023-11-11
  • Spring3 MVC请求参数获取的几种方法小结

    Spring3 MVC请求参数获取的几种方法小结

    本篇文章主要介绍了Spring3 MVC请求参数获取的几种方法小结,非常具有实用价值,需要的朋友可以参考下。
    2017-03-03
  • 实时计算知多少?

    实时计算知多少?

    这篇文章对滑动窗口计数的概念和关键代码做了较为详细解释,让我们对实时计算这一概念有了更深的了解,需要的朋友可以参考下
    2015-07-07
  • java组件fileupload文件上传demo

    java组件fileupload文件上传demo

    这篇文章主要为大家详细介绍了java组件fileupload文件上传demo ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • 解决使用httpclient传递json数据乱码的问题

    解决使用httpclient传递json数据乱码的问题

    这篇文章主要介绍了解决使用httpclient传递json数据乱码的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • Java编程关于子类重写父类方法问题的理解

    Java编程关于子类重写父类方法问题的理解

    这篇文章主要介绍了Java编程关于子类重写父类方法问题的理解,分享了有关子类重写父类的实例,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • Java排序算法之冒泡排序的原理及优化

    Java排序算法之冒泡排序的原理及优化

    这篇文章主要介绍了Java排序算法之冒泡排序的原理及优化,冒泡排序的思想很简单,遍历数组,比较相邻的两个元素,顺序错误就把它们交换,直到整个数组排序完成,因为每经过一趟排序,越小的元素会经交换而慢慢“浮”到数列的顶端,因此叫做冒泡排序,需要的朋友可以参考下
    2023-11-11
  • El表达式使用问题javax.el.ELException:Failed to parse the expression的解决方式

    El表达式使用问题javax.el.ELException:Failed to parse the expression

    今天小编就为大家分享一篇关于Jsp El表达式使用问题javax.el.ELException:Failed to parse the expression的解决方式,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12

最新评论