• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

java 自动拆装箱特性

互联网 diligentman 2小时前 4次浏览

文章目录

  • 一、自动装拆箱是什么?
  • 二、拆装箱的使用
    • 1.引入包装类的原因:
    • 2.自动拆装箱的运用
    • 3.一些典型举例

一、自动装拆箱是什么?

  • 有时,需要将int这样的基本类型转换为对象。所有的基本类型都有一个与之对应的类,例如 Integer类对应基本类型int。通常,这些类被称为包装器。

  • 这些包装类对应基本数据类型:
    Integer , Long , Float , Short , Byte, Charater , Boolen;
    (前六个类派生于公共的超类Number)

  • 包装类是不可变的,即一旦构造了包装器,就不允许更改包装在其中的值,同时,包装类还是final,因此不能派生他的子类。

二、拆装箱的使用

1.引入包装类的原因:

  1. 包装成对象后更加方便操作,比如可以直接封装一些方法放在类中方便使用:比如,将一个数字字符串s转换成数值 可以使用:int x = Integer.parseInt(s)
  2. 或者能方便将数据加入集合:假如想要定义一个整型数组列表。遗憾的是,尖括号中的类型参数不允许是基本类型,也就是说,不允许写成如 ArrayList,这里就可以用到Integer 包装类。
    我们可以声明一个Integer对象的数组列表:
    ArrayList list = new ArrayList()

注:由于每个值分别包装在对象中,所以ArrayList的执行效率远低于int[ ]数组。因此,只有当操作的方便性比执行效率更重要时,才会考虑对较小的集合使用这种构造

2.自动拆装箱的运用

  1. 对于向ArrayList()中添加int类型的元素 就可以用到自动装箱的特性,下面这个调用:
    list.add(3);
    将自动变换成:
    list.add(Integer.valueOf(3));
    这就是 自动装箱(autoboxing)
  2. 相反的 当将一个Integer对象赋给一个int值时,将会自动拆箱。也就是说,编译器将以下语句:
    int n=list.get(i);
    转换成:
    int n =list.get(i).intValue();
    这就是 自动拆箱

3.一些典型举例

  1. 自动拆装箱适用于算术表达式。例如,可以将自增运算符应用于包装类引用:
    Integer n =1;
    n++;
    编译器将自动插入一条对象拆箱的指令,然后进行自增运算,最后再将结果拆箱。
  2. ==运算符和包装类联用的注意
    (以下内容谈到了 运行时常量池,如果需要搞清楚请移步这篇文章)

(1)自动装箱常见的就是valueOf这个方法,自动拆箱就是intValue方法。在它们的源码中有一段代码定义了包装类的缓冲区。除了两个包装类Long和Double 没有实现这个缓存技术,其它的包装类均实现了它。
如下代码:

Integer i1 = 40;
Integer i2 = 40;
Double i3 = 40.0Double i4 = 40.0System.out.println("i1=i2   " + (i1 == i2));
System.out.println("i3=i4   " + (i3 == i4));

-----结果----
true
false

原理如下:
“==” 这个运算在不出现算数运算符的情况下 不会自动拆箱,所以i1 和 i 2它们不是数值进行的比较,仍然是比较地址是否指向同一块内存,在integer源码中缓冲区的范围是-128-127之间,在此范围内只要不new对象,那么数值的地址都是相同的,都在常量池区域。而Double没有设置缓冲区,自然i3 i4的地址不相同。
所以包装类对象比较时最好调用equals方法。

  1. (1)由于包装类引用可以为NULL,所以自动装箱有可能会抛出一个NullPointerException异常:
    eg:Integer n =null; System.out.println(2*n);
    (2)另外,如果在一个条件表达式中混合使用Integer和Double类型,Integer值会拆箱,提升为double再装箱为Double;

                                          引用--《java核心技术卷一》
    

程序员灯塔
转载请注明原文链接:java 自动拆装箱特性
喜欢 (0)