JAVA int a = 1 中发生了什么

JAVA int a = 1 中发生了什么

测试代码

javac TestCode.java

 public class TestCode {
     public static void main(String[] args) {
         int aaaa = 1;
         aaaa = 2;
     }
 }

反编译

javap -v -p -l TestCode(l是小写的L)

注解:javap是jdk自带的反解析工具。作用是根据class字节码文件,反解析出当前类对应的code区(汇编指令)、本地变量表、异常表和代码行偏移量映射表、常量池等等信息。

 Classfile xxxxx/com/code/baseCode/TestCode.class
   Last modified 2021-11-21; size 436 bytes
   MD5 checksum c2864ab4f514372ff51ed92e384bb437
   Compiled from "TestCode.java"
 public class com.code.baseCode.TestCode
   minor version: 0
   major version: 52
   flags: ACC_PUBLIC, ACC_SUPER
 Constant pool:
    #1 = Methodref          #3.#19         // java/lang/Object."<init>":()V
    #2 = Class              #20            // com/code/baseCode/TestCode
    #3 = Class              #21            // java/lang/Object
    #4 = Utf8               <init>
    #5 = Utf8               ()V
    #6 = Utf8               Code
    #7 = Utf8               LineNumberTable
    #8 = Utf8               LocalVariableTable
    #9 = Utf8               this
   #10 = Utf8               Lcom/code/baseCode/TestCode;
   #11 = Utf8               main
   #12 = Utf8               ([Ljava/lang/String;)V
   #13 = Utf8               args
   #14 = Utf8               [Ljava/lang/String;
   #15 = Utf8               aaaa
   #16 = Utf8               I
   #17 = Utf8               SourceFile
   #18 = Utf8               TestCode.java
   #19 = NameAndType        #4:#5          // "<init>":()V
   #20 = Utf8               com/code/baseCode/TestCode
   #21 = Utf8               java/lang/Object
 {
   public com.code.baseCode.TestCode();
     descriptor: ()V
     flags: ACC_PUBLIC
     Code:
       stack=1, locals=1, args_size=1
          0: aload_0
          1: invokespecial #1                  // Method java/lang/Object."<init>":()V
          4: return
       LineNumberTable:
         line 8: 0
       LocalVariableTable:
         Start  Length  Slot  Name   Signature
             0       5     0  this   Lcom/code/baseCode/TestCode;
 ​
   public static void main(java.lang.String[]);
     descriptor: ([Ljava/lang/String;)V
     flags: ACC_PUBLIC, ACC_STATIC
     Code:
       stack=1, locals=2, args_size=1
          0: iconst_1
          1: istore_1
          2: iconst_2
          3: istore_1
          4: return
       LineNumberTable:
         line 11: 0
         line 12: 2
         line 52: 4
       LocalVariableTable:
         Start  Length  Slot  Name   Signature
             0       5     0  args   [Ljava/lang/String;
             2       3     1  aaaa   I
 }
 SourceFile: "TestCode.java"

反编译后,会发现aaaa存在于Constant pool(常量池)和LocalVariableTable(本地变量表)中

常量池解释

JVM中有Class常量池、运行时常量池、全局字符串常量池、基本类型包装类常量池。

  • Class常量池:主要存放字面量和符号引用。 详情可看字面量,符号引用,直接引用究竟是什么?

    • 字面量就是固定值,int a = 1,String a = "abc",其中1和abc就是字面量,但java中字面量必须是final修饰

    • 由于在编译过程中并不知道每个类的地址,因为可能这个类还没有加载,所以如果你在一个类中引用了另一个类,那么你完全无法知道他的内存地址,那怎么办,我们只能用他的类名作为符号引用,在类加载完后用这个符号引用去获取他的内存地址。

  • 运行时常量池:运行时常量池部分数据是来自于Class常量池,其具有动态性。在Class常量池中存储着字面量和符号引用,其中符号引用会在加载时,将Class中字节流代表的静态存储转换为方法区的运行时数据结构。不同的类用同一个运行时常量池。

  • 字符串常量池:JVM所维护的一个字符串实例的引用表。运行时常量池在方法区中,JDK1.7后,字符串常量池移到了堆中。

  • java中基本类型的包装类的大部分都实现了常量池技术,这些类是Byte,Short,Integer,Long,Character,Boolean,另外两种浮点数类型的包装类则没有实现。另外上面这5种整型的包装类也只是在对应值小于等于127时才可使用对象池,也即对象不负责创建和管理大于127的这些类的对象。

上面JVM常量池介绍信息来自于

这一次,彻底弄懂java中的常量池 - 掘金

终于搞懂了Java 8 的内存结构,再也不纠结方法区和常量池了!! - 掘金

jvm中class文件常量池中存放了哪些信息?/常量池为什么有变量名称呢?

JVM中Class文件常量池中存放了哪些信息_wenpan的博客-CSDN博客_jvm常量池存放哪些东西

JVM常量池浅析 - 简书

局部变量表和操作数栈?

【JVM】1.1、局部变量表与操作数栈 - 简书

图片解释

java1.8的内存布局

image-20211122224530763

在编译后内存情况

类文件结构:类文件结构 - 掘金

image-20211122225026358

运行时发生情况

其中java byte code为

如何查看Java bytecode指令?

https://en.wikipedia.org/wiki/List_of_Java_bytecode_instructions

Jvm系列3—字节码指令 - Gityuan博客 | 袁辉辉的技术博客

image-20211122225541864

上面注意的地方是,变量1指的是LocalVariableTable中的第一个变量,也就是aaaa。

iconst_1

image-20211122231250791

istore_1

image-20211122231603974

iconst_2

image-20211122231651367

istore_1

image-20211122232005905

结尾

上述是基础数据类型的情况,后续出String类型,以及包装类型的情况

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值