jvm各个变量初始化的过程

本文反汇编的版本是1.8

对主要几个变量初始化过程进行了解析

代码如下

public int testForException() {
		int a = 'a';
		char c1 = 'a';
		int i1 = 1;
		double d1 = 0.2;
		long l1 = 100l;
		EntityFF entityFF = new EntityFF();
		entityFF.getName();
		return 1;
	}

反汇编如下

 Code:
      stack=2, locals=9, args_size=1
         0: bipush        97
         2: istore_1
         3: bipush        97
         5: istore_2
         6: iconst_1
         7: istore_3
         8: ldc2_w        #16                 // double 0.2d
        11: dstore        4
        13: ldc2_w        #18                 // long 100l
        16: lstore        6
        18: new           #20                 // class com/smp/util/fordev/EntityFF
        21: dup
        22: invokespecial #22                 // Method com/smp/util/fordev/EntityFF."<init>":()V
        25: astore        8
        27: aload         8
        29: invokevirtual #23                 // Method com/smp/util/fordev/EntityFF.getName:()Ljava/lang/String;
        32: pop
        33: iconst_1
        34: ireturn

常量池如下

Constant pool:
   #1 = Class              #2             // com/smp/util/fordev/MainFunc
   #2 = Utf8               com/smp/util/fordev/MainFunc
   #3 = Class              #4             // java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Utf8               Code
   #8 = Methodref          #3.#9          // java/lang/Object."<init>":()V
   #9 = NameAndType        #5:#6          // "<init>":()V
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcom/smp/util/fordev/MainFunc;
  #14 = Utf8               testForException
  #15 = Utf8               ()I
  #16 = Double             0.2d
  #18 = Long               100l
  #20 = Class              #21            // com/smp/util/fordev/EntityFF
  #21 = Utf8               com/smp/util/fordev/EntityFF
  #22 = Methodref          #20.#9         // com/smp/util/fordev/EntityFF."<init>":()V
  #23 = Methodref          #20.#24        // com/smp/util/fordev/EntityFF.getName:()Ljava/lang/String;
  #24 = NameAndType        #25:#26        // getName:()Ljava/lang/String;
  #25 = Utf8               getName
  #26 = Utf8               ()Ljava/lang/String;
  #27 = Utf8               a
  #28 = Utf8               I
  #29 = Utf8               c1
  #30 = Utf8               C
  #31 = Utf8               i1
  #32 = Utf8               d1
  #33 = Utf8               D
  #34 = Utf8               l1
  #35 = Utf8               J
  #36 = Utf8               entityFF
  #37 = Utf8               Lcom/smp/util/fordev/EntityFF;
  #38 = Utf8               SourceFile
  #39 = Utf8               MainFunc.java

1、将'a'复制给int或者char都是当做int去处理的,这里用了bipush 如果数值是-1~5的话 用的是iload,这里可以看到int a = 'a' 和char a = 'a'是一样的字节码,所以二者不存在效率区别

2、变量初始化的过程一般是两步,第一步加载到操作数栈,第二部从操作数栈加载到变量里。

3、double和long使用的都是ldc2_w指令,long类型如果数值小的话是lconst

4、对象新建的过程有很多,这里只给了new的例子,首先new一个对象,new的操作数是指向常量池的#20,对应一个class,class包含一个操作数是类名,指向#21,new指令的操作是创建一个对象,将其引用进栈,dup是复制栈顶元素,将复制值入栈。

5、调用方法也是调用常量池,常量池中的参数引用通常也来源于常量池,通过对应名字都可以看出大概意思

6、其中方法的表示()V就表示没有参数,返回值为void的函数,如果是(I)I就是参数是int,返回值是int,如果参数是String之类的对象,这里用的就是全限定名

猜你喜欢

转载自blog.csdn.net/a397525088/article/details/81662650