Java字节码是否由JVM顺序执行?

Java字节码是否由JVM顺序执行?,java,bytecode,Java,Bytecode,我对Java字节码非常陌生。据我所知,在反汇编JAR文件时,结果将是JVM直接解释的字节码(数字)。每个字节或2个字节的数字都与实际Java源文件中的一个Java方法相关联。我在哪里可以找到这些的映射 此外,假设我想知道一个变量是否在一个类中被初始化,但之后就再也没有使用过。我是否可以简单地检查它是何时被实例化的,然后如果它在初始化后再也没有出现在字节码中,就认为它从未被使用过?为了使这种逻辑正常工作,JVM必须按顺序执行字节码,这样初始化的变量就不能跳转到另一个函数,等等。函数边界的定义不同于

我对Java字节码非常陌生。据我所知,在反汇编JAR文件时,结果将是JVM直接解释的字节码(数字)。每个字节或2个字节的数字都与实际Java源文件中的一个Java方法相关联。我在哪里可以找到这些的映射

此外,假设我想知道一个变量是否在一个类中被初始化,但之后就再也没有使用过。我是否可以简单地检查它是何时被实例化的,然后如果它在初始化后再也没有出现在字节码中,就认为它从未被使用过?为了使这种逻辑正常工作,JVM必须按顺序执行字节码,这样初始化的变量就不能跳转到另一个函数,等等。函数边界的定义不同于一般汇编代码(intel,MIPS)


提前谢谢。

这里不完全清楚你在问什么,所以让我回答一些问题:

与“普通”汇编代码不同,方法边界定义良好。类型在任何地方都有很好的定义。字段定义良好。类是定义良好的。指令边界定义良好(跳到指令中间是非法的)。代码和数据很容易区分。方法不能访问彼此的变量;只有字段。这些东西使得分析Java字节码比分析机器代码容易得多

要从Java程序读取和写入类文件,我建议使用。它将负责理解类文件格式,并将其转换为更易于使用的格式(Java对象树或方法调用序列)。还有其他类似用途的库,如BCEL、cgLib和Javassist。我对那些其他图书馆不够熟悉,无法进行比较

对于“大多数”指令,方法中的字节码是按顺序执行的。有几个指令可能导致执行不连续-通常这是指令的目的(例如,条件跳转,用于在执行
时执行
/
,而
/等)。许多指令还可以抛出异常,这会导致执行跳转到异常处理程序或退出当前方法

以下说明会影响控制流:

  • areturn
    dreturn
    freturn
    ireturn
    lreturn
    -执行时,使方法正常返回。在极少数情况下(错误生成字节码),也可以抛出非法监视器状态异常
  • athrow
    -执行时,引发异常
  • 如果icmpne
    如果icmpeq
    如果icmplt
    如果icmpge
    如果icmpgt
    如果icmple
    如果icmple
    ifeq
    ifge
    ifge
如果icmple
如果无条件跳转指令
  • goto
    goto\u w
    -无条件跳转指令
  • aaload
    aastore
    anewarray
    数组长度
    baload
    bastore
    caload
    castore
    daload
    dastore
    faload
    fastore
  • iaload
    iastore
    idiv
    instanceof
    irem
    laload
    lastore
    ldc
    ldc2\w
    ldiv
    lrem,
    newarray
    putfield
    putstatic
    saload
    sastore
    -在某些情况下可能引发异常
  • invokedynamic
    invokeinterface
    invokespecial
    invokestatic
    invokevirtual
    new
    -导致调用其他方法,这可能导致引发异常
  • jsr
    jsr\u w
    ret
    -允许方法包含从多个位置调用的子例程。幸运的是,现代编译器似乎并没有生成这些

    • 你在这里问的问题并不完全清楚,所以让我回答一些问题:

      与“普通”汇编代码不同,方法边界定义良好。类型在任何地方都有很好的定义。字段定义良好。类是定义良好的。指令边界定义良好(跳到指令中间是非法的)。代码和数据很容易区分。方法不能访问彼此的变量;只有字段。这些东西使得分析Java字节码比分析机器代码容易得多

      要从Java程序读取和写入类文件,我建议使用。它将负责理解类文件格式,并将其转换为更易于使用的格式(Java对象树或方法调用序列)。还有其他类似用途的库,如BCEL、cgLib和Javassist。我对那些其他图书馆不够熟悉,无法进行比较

      对于“大多数”指令,方法中的字节码是按顺序执行的。有几个指令可能导致执行不连续-通常这是指令的目的(例如,条件跳转,用于在执行
      时执行
      /
      ,而
      /等)。许多指令还可以抛出异常,这会导致执行跳转到异常处理程序或退出当前方法

      以下说明会影响控制流:

      • areturn
        dreturn
        freturn
        ireturn
        lreturn
        -执行时,使方法正常返回。在极少数情况下,也可以抛出非法监视器状态异常
        package p1;
        
        public class Movie {
          public void setPrice(int price) {
            this.price = price;
          }
        }
        
        public class p1.Movie {
          public p1.Movie();
            Code:
               0: aload_0       
               1: invokespecial #10   // Method java/lang/Object."<init>":()V
               4: return        
        
          public void setPrice(int);
            Code:
               0: aload_0       
               1: iload_1       
               2: putfield      #18    // Field price:I
               5: return        
        }
        
        | this |
        +------+
        
        | price |
        | this  |
        +-------+
        
        Classfile /home/imaman/workspace/Movie-shop/bin/p1/Movie.class
        ...
        Constant pool:
           #1 = Class              #2             //  p1/Movie
           ...
           #5 = Utf8               price
           #6 = Utf8               I
           ...
           #18 = Fieldref          #1.#19          //  p1/Movie.price:I
           #19 = NameAndType       #5:#6           //  price:I
           ...
        
        LDC 10    // Push the constant 10 onto the stack.
        LDC 20    // Push the constant 20 onto the stack.
        IADD      // Pop two numbers off the stack, add them, push the result.
        ISTORE 5  // Pop an integer (in this case 30) off the stack and put it in variable #5.