「java」深度剖析自动装箱与拆箱

目录

一.基本数据类型与包装类的对应关系:

1.以下代码结果为什么不同?

2.浅谈Integer i = new Integer(xxx)和Integer i =xxx;这两种方式的区别:

Hellow!大家好,我是Node_Hao!今天给大家带来的是 java包装类中的自动装箱与拆箱 ,虽然这不是一个很复杂的知识点,但其中的 部分细节却是面试官经常问到的 ,希望这篇文章能带给你启发!

一.基本数据类型与包装类的对应关系:

基本数据类型

包装类

byte

Byte

short

Short

int

Integer

long

Long

float

Float

double

Double

char

Character

boolean

Boolean

由以上对应关系我们可以看出,基本数据类型的包装类,除了 Intege r 和 Character 其 余都是首字母大写.

二.包装类基本介绍:

1.为何引入包装类:

初学包装类我们都非常疑惑,既然已经有了基本数据类型,为什么需要包装类?其实,随着我们对java面向对象的理解不断深入,我们会发现在 万物皆对象 的java语言中,其基本数据类型居然不是面向对象的,这不 仅给类型之间的转化带来了很多麻烦,在基本数据类型的基础上也很难有更多的操作 ,为了解决这类问题在 JDK1.5 引入了两个功能:1. 自动装箱 2. 自动拆箱.

2.自动装箱与拆箱

  • 自动装箱 : 当我们把 基本数据类型 赋值给 引用类型 时,系统会将它自动包装成所需的实例对象,这样基本数据类型就达到了 面向对象的效果.
  • 自动拆箱 :当我们需要 基本数据类型 但此时传入的是 包装类型 ,系统会自动拆箱,把 包装类的值剥离出来.

1)隐式拆装箱:

public static void main4(String[] args) {        Integer a = 123;//装箱        int b = a;//拆箱[隐式的]}

为什么叫隐式呢?我们来看反编译:

通过反编译我们发现,在执行以上代码的过程中,编译器自动调用了 Integer.valueof() 方法装箱, intValue() 方法拆箱.

2)显示拆装箱:

Integer a2 = Integer.valueOf(123);//显示装箱int b2 = a2.intValue();//显示拆箱

通过以上代码我们可以发现, 装箱与拆箱的过程我们都可以看到 ,所以叫显示拆装箱.

三.面试常问:

1.以下代码结果为什么不同?

通过前面知识我们可知给 Integer赋值相当于隐式装箱 ,系统会自动调用 Integer.valueof() 方法.所以我们只需要查看 Integer.valueof() 方法的源码即可.

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

cache 为缓存的意思,所以我们推测 Integer.valueof() 方法的返回值有一定的范围,那么这个范围是多大呢?我们可以查看 low 和 high 的原码.

private static class IntegerCache {        static final int low = -128;        static final int high;        static final Integer[] cache;        static Integer[] archivedCache;        static {            // high value may be configured by property            int h = 127;}

由此我们明白了, Integer.valueof() 方法的底层是一个 缓存数组 ,数组的大小范围是 -128到127 ,如果我们输入的元素恰好在这个范围, valueof()方法便会指向cache数组中存在的引用 ,否则会创建一个新的Integer对象,指向的地址不同那么值自然也就不同了.

注意 :除了 Double 和 Float 类型的valueof()方法外,其他基本类型的valueof()方法实现过程类似.这是因为 浮点数的存储相较于其他类型会更加的复杂 ,我们可以简单观察一下源码. 感兴趣的读者下来可以深入了解一下,这里不过多讲述.

2.浅谈Integer i = new Integer(xxx)和Integer i =xxx;这两种方式的区别:

        据了解Integer i = new Integer(xxx)这个方法已经过时,新一点的编译器可能无法通过编译.这恰好体现了new Integer(xxx)的不足之处:1.new Integer(xxx)不会触发自动装箱机制,而第Integer i =xxx会.2.执行效率上Integer i =xxx会更快.

3.综合考察:

public static void main(String args[]){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())));}

第一个和第二个之前已经讲过,是 valueof() 方法的范围问题,这里不过多赘述.第三个 算数运算 会触发自动拆箱I nteger.valueof() 方法,所以比较的是数组大小.第四个括号中的算数运算会先触发自动拆箱机制,之后又触发自动装箱机制,由于在cache数组的范围之内,所以为true.第五个也是同样的原理,第六个和第七个主要考察 Long.valueof() 的自动装箱类型只能和自己类型的比较.

以上就是深度剖析自动装箱与拆箱的全部内容了,如果我的总结对你有所启发和帮助,码字不易,麻烦给个三连哦!

原文 https://blog.csdn.net/liu_xuixui/article/details/126032513

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章