Java自动装箱、拆箱,原理你竟然不知道

基本数据类型与包装类型装箱、拆箱

基本 长度 包装类型

byte 1B Byte

short 2B Short

int 4B Integer

long 8B Long

float 4B Float

double 8B Double

boolean 1B Boolean

char 1B Character

什么是包装类型?

对基本数据类型进行一层封装,将其封装成了,具有类的特性

比如int的包装类型Integer,内部封装了一个int类型的value

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WXAxfWrx-1595571197504)(/Users/chentao/Documents/md_img/image-20200723181136136.png)]

其他的包装类型类似,也在内部封装了对应的基本数据类型

封装的基本数据类型用final修饰,即一旦确定就不可以在变

为什么要有包装类型?

Java是面向对象的语言,基本数据类型不是对象,导致多有不便,比如HashMap等容器只能装对象,不能直接装基本数据类型,sychornized不能对基本数据类型上锁等等

怎么使用包装类型?

包装类型就是封装了一个对应的基本数据类型的类,使用包装类型跟使用普通的类一样,new即可。

常用方法:

valueOf(),静态方法,可以将某个类或基本变量转换成对应的包装类型

    public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
    }//Integer的valueOf方法,可以将String转换成Integer,即创建一个value=s的int值的Integer

xxValue(),静态方法,可以获得对应内部的基本类型的值,如果xx是int,那么获取的值类型转为int型

    public int intValue() {
        return value;
    }//可以看到Integer中的intValue直接返回了value,value是Integer内部封装的int基本类型
    public long longValue() {
        return (long)value;
    }//longValue将value强转为了long

常用属性:

MIN_VALUE,静态属性,获取该类型能表示的最大值

MAX_VALUE,静态属性,获取该类型能表示的最小值

自动装箱、拆箱

前面说到,包装类型的产生是为了解决不是基本数据类型不是对象,导致很多情况不能使用。

但是也带来了不变,比如对于基本数据类型int,可以直接使用+ - * / %等操作,但是如果是包装类型,由于java没有运算符重载,不能这样使用。

于是Java提供了自动装箱、拆箱。

自动装箱基本数据类型在需要的时候可以隐式转换为包装类型

//不采用自动装箱
Integer i1 = new Integer(1);
//自动装箱
Integer i2 = 1;
Integer i3 = i1+2;
System.out.println(i1+" "+i2+" "+i3);

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DNszNMzk-1595571197508)(/Users/chentao/Documents/md_img/image-20200724135825748.png)]

自动拆箱包装类型在需要的时候自动的隐式转换为基本数据类型

Integer i1 = new Integer(1);
//不采用自动拆箱
int i2 = i1.intValue();
//自动拆箱
int i3 = i1;
System.out.println(i1+" "+i2+" "+i3);

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6WfrvsOa-1595571197519)(/Users/chentao/Documents/md_img/image-20200724140841456.png)]

装箱、拆箱原理

都是编译器的功劳,装箱、拆箱是在编译器编译的时候,进行的。

自动装箱

将前面自动装箱的代码编译后的字节码文件进行反编译

这里我是用jd-GUI来反编译,笔者本身的IDE是Idea,但是Idea好像反编译后,把内容全部直接拆箱了,因此使用Idea不能窥其究竟。

    Integer i1 = new Integer(1);
    Integer i2 = Integer.valueOf(1);//原来代码 Integer i2 = 1;
    Integer i3 = Integer.valueOf(i1.intValue() + 2);//原来代码 Integer i3 = i1+2;
    System.out.println(i1 + " " + i2 + " " + i3);

与之前的代码对比,是否一目了然。

原来如此.jpg

在经过javac编译后,自动装箱即使用对应包装类型的valueOf方法

自动拆箱

同样的,将前面自动拆箱的代码编译后的字节码文件进行反编译

Integer i1 = new Integer(1);
int i2 = i1.intValue();
int i3 = i1.intValue();//原来代码 int i3 = i1;
System.out.println(i1 + " " + i2 + " " + i3);

在经过javac编译后,自动拆箱即使用对应包装类型的xxValue方法

这一切都发生在编译层面,因此不会对JVM指令有任何的影响

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值