反编译字节码分析java包装类型和引用类型及装箱与拆箱

4 篇文章 0 订阅

1 缘起

补充字节码相关知识时,发现基础数据类型、包装类型和引用类型在字节码层面的差异,
未接触字节码前,只是理论上直到数据存储方式不同,
没有证明材料,通过反编译字节码,发现,不同的数据大类型,分配空间是不同的,
分享如下,帮助读者进一步了解基础数据类型、包装类型和引用类型的差别。

2 数据类型

2.1 基础数据类型

基础数据类型存储在栈中,直接申请内存。
Java提供8中基础数据类型,int、long、float、double、boolean、char、byte和short。

2.2 包装类型

包装类型:基础数据类型对应的类。
在栈中存储引用,堆中存储数据。
与基础数据类型一一对应,因此,也有8中包装类型,对应关系:
在这里插入图片描述

包装类型,既然是包装,则有装和拆的概念,这里是装箱和拆箱。

  • 装箱:将数据存储为对象,如Integer.valueOf()T;
  • 拆箱:将对象转为基础类型,如var1.intValue();

2.3 引用类型

引用类型有三种:类、接口和数组,
栈中存储引用,堆中存储实际内容。

3 Code实践

源码默认情况下会折叠,为方便查看,
先给出源码对应的字节码关系结果,
后面会给出完整的源码。
字节码解析https://blog.csdn.net/Xin_101/article/details/126288966

3.1 基础类型

基础类型及字节码对应关系如下图所示。
怎么证明是基础数据类型?
字节码关系如下图所示:
在这里插入图片描述

3.2 包装类型

基础数据类型对应的包装类类型及对应的字节码关系如下图所示。
证明包装类型为引用类型存储。
在这里插入图片描述

3.3 引用类型

引用类型及对应的字节码如下图所示。
在这里插入图片描述

源码

package com.monkey.java_study.clzz;

import com.monkey.java_study.common.entity.UserEntity;
import com.monkey.java_study.proxy.jdk_proxy.IUserService;
import com.monkey.java_study.proxy.jdk_proxy.impl.UserServiceImpl;

/**
 * 数据类型字节码测试.
 *
 * @author xindaqi
 * @since 2022-08-12 15:26
 */
public class DataTypeByteCodeTest {

    public void basicType() {
        // iconst_1
        // istore_1
        int var1 = 1;

        // lconst_1
        // lstore_2
        long var2 = 1L;

        // fconst_1
        // fstore
        float var3 = 1.0f;

        // dconst_1
        // dstore
        double var4 = 1.0;

        // iconst_1
        // istore
        boolean var5 = true;

        // bipush
        // istore
        char var6 = 'a';

        // bipush
        // istore
        byte var7 = 0x10;

        // iconst_1
        // istore
        short var8 = 1;
    }

    public void packageType() {
        // iconst_1
        // invokestatic:自动装箱
        // astore_1
        Integer var1 = 1;

        // lconst_1
        // invokestatic:自动装箱
        // astore_2
        Long var2 = 1L;

        // fconst_1
        // invokestatic:自动装箱
        // astore_3
        Float var3 = 1.0f;

        // dconst_1
        // invokestatic:自动装箱
        // astore
        Double var4 = 1.0;

        // iconst_1
        // invokestatic:自动装箱
        // astore
        Boolean var5 = true;

        // bipush
        // invokestatic:自动装箱
        // astore
        Character var6 = 'a';

        // iconst_1
        // invokestatic:自动装箱
        // astore
        Byte var7 = 0x01;

        // iconst_1
        // invokestatic:自动装箱
        // astore
        Short var8 = 1;
    }

    public void referenceType() {
        // new
        // dup
        // invokespecial
        // astore_1
        UserEntity userEntity = new UserEntity();

        // new
        // dup
        // invokespecial
        // astore_2
        IUserService userService = new UserServiceImpl();

        // iconst_2
        // newarray
        // dup
        // iconst_0
        // iconst_0
        // iastore
        // dup
        // iconst_1
        int[] var1 = {0, 1};
    }

    public static void main(String[] args) {
    }
}

4 反编译

4.1 基础数据类型

源码与字节码映射关系如下图所示。
在这里插入图片描述

4.2 包装类型

源码与字节码映射关系如下图所示。
在这里插入图片描述

4.3 引用类型

源码与字节码映射关系如下图所示。
在这里插入图片描述

完整结果

PS D:\java-basic-with-maven\target\classes\com\monkey\java_study\clzz> javap -c .\DataTypeByteCodeTest.class
Compiled from "DataTypeByteCodeTest.java"
public class com.monkey.java_study.clzz.DataTypeByteCodeTest {
  public com.monkey.java_study.clzz.DataTypeByteCodeTest();   
    Code:                                                     
       0: aload_0                                                                  
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return                                                                   

  public void basicType();
    Code:
       0: iconst_1
       1: istore_1
       2: lconst_1
       3: lstore_2
       4: fconst_1
       5: fstore        4
       7: dconst_1
       8: dstore        5
      10: iconst_1
      11: istore        7
      13: bipush        97
      15: istore        8
      17: bipush        16
      19: istore        9
      21: iconst_1
      22: istore        10
      24: return

  public void packageType();
    Code:
       0: iconst_1
       1: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       4: astore_1
       5: lconst_1
       6: invokestatic  #3                  // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
       9: astore_2
      10: fconst_1
      11: invokestatic  #4                  // Method java/lang/Float.valueOf:(F)Ljava/lang/Float;
      14: astore_3
      15: dconst_1
      16: invokestatic  #5                  // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      19: astore        4
      21: iconst_1
      22: invokestatic  #6                  // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
      25: astore        5
      27: bipush        97
      29: invokestatic  #7                  // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      32: astore        6
      34: iconst_1
      35: invokestatic  #8                  // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
      38: astore        7
      40: iconst_1
      41: invokestatic  #9                  // Method java/lang/Short.valueOf:(S)Ljava/lang/Short;
    Code:
       0: return
}

5 小结

(1)基础数据类型存储在栈中,直接申请内存,Java提供8中基础数据类型,int、long、float、double、boolean、char、byte和short;
(2)包装类型:基础数据类型对应的类。在栈中存储引用,堆中存储数据;
(3)装箱:将数据存储为对象,如Integer.valueOf()T;拆箱:将对象转为基础类型,如var1.intValue();
(4)引用类型有三种:类、接口和数组,栈中存储引用,堆中存储实际内容。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天然玩家

坚持才能做到极致

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值