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


    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) {
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117

    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."":()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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    5 小结

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

  • 相关阅读:
    功能测试想进阶,可以提供一点点思路和方向吗?
    python opencv 持续点选开始帧,结束帧,切割视频成几个小段
    【分享】一个神经网络(层数+类型)在线测试 平台
    基于MSCNN算法的python编程实现的人群密度检测系统
    基于注意力机制的LSTM液体管道非稳态工况检测
    C# 基础面试题(万字)
    信息熵原理与Python实现
    MongoDB——写入耗时
    简明SQL条件查询指南:掌握WHERE实现数据筛选
    【数学建模】——力学模型建立的基本理论及方法
  • 原文地址:https://blog.csdn.net/Xin_101/article/details/126297783