java字节码分析工具javap

源代码

package org.example;

public class Main {
    public static void main(String[] args) {
        int a = 1;
        while (a < 10) {
            a++;
            if (a < 5) {
                System.out.println("a<5");
            } else {
                System.out.println("a>=5");
            }
        }
    }
}

语法树

<?xml version='1.0' encoding='UTF-8' ?>
<CompilationUnit Image='' PackageName='org.example' declarationsAreInDefaultPackage='false'>
    <PackageDeclaration Image='' Name='org.example' PackageNameImage='org.example'>
        <Name Image='org.example' />
    </PackageDeclaration>
    <TypeDeclaration Image=''>
        <ClassOrInterfaceDeclaration Abstract='false' BinaryName='org.example.Main' Default='false' Final='false' Image='Main' Interface='false' Local='false' Modifiers='1' Native='false' Nested='false' NonSealed='false' PackagePrivate='false' Private='false' Protected='false' Public='true' Sealed='false' SimpleName='Main' Static='false' Strictfp='false' Synchronized='false' Transient='false' TypeKind='CLASS' Volatile='false'>
            <ClassOrInterfaceBody AnonymousInnerClass='false' EnumChild='false' Image=''>
                <ClassOrInterfaceBodyDeclaration AnonymousInnerClass='false' EnumChild='false' Image='' Kind='METHOD'>
                    <MethodDeclaration Abstract='false' Arity='1' Default='false' Final='false' Image='' InterfaceMember='false' Kind='METHOD' MethodName='main' Modifiers='17' Name='main' Native='false' PackagePrivate='false' Private='false' Protected='false' Public='true' Static='true' Strictfp='false' Synchronized='false' SyntacticallyAbstract='false' SyntacticallyPublic='true' Transient='false' Void='true' Volatile='false'>
                        <ResultType Image='' Void='true' returnsArray='false' />
                        <MethodDeclarator Image='main' ParameterCount='1'>
                            <FormalParameters Image='' ParameterCount='1' Size='1'>
                                <FormalParameter Abstract='false' Array='true' ArrayDepth='1' Default='false' ExplicitReceiverParameter='false' Final='false' Image='' Modifiers='0' Native='false' PackagePrivate='true' Private='false' Protected='false' Public='false' Static='false' Strictfp='false' Synchronized='false' Transient='false' TypeInferred='false' Varargs='false' Volatile='false'>
                                    <Type Array='true' ArrayDepth='1' ArrayType='true' Image='' TypeImage='String'>
                                        <ReferenceType Array='true' ArrayDepth='1' Image=''>
                                            <ClassOrInterfaceType AnonymousClass='false' Array='true' ArrayDepth='1' Image='String' ReferenceToClassSameCompilationUnit='false' />
                                        </ReferenceType>
                                    </Type>
                                    <VariableDeclaratorId Array='false' ArrayDepth='0' ArrayType='true' ExceptionBlockParameter='false' ExplicitReceiverParameter='false' Field='false' Final='false' ForeachVariable='false' FormalParameter='true' Image='args' LambdaParameter='false' LocalVariable='false' Name='args' PatternBinding='false' ResourceDeclaration='false' TypeInferred='false' VariableName='args' />
                                </FormalParameter>
                            </FormalParameters>
                        </MethodDeclarator>
                        <Block Image='' containsComment='false'>
                            <BlockStatement Allocation='false' Image=''>
                                <LocalVariableDeclaration Abstract='false' Array='false' ArrayDepth='0' Default='false' Final='false' Image='' Modifiers='0' Native='false' PackagePrivate='true' Private='false' Protected='false' Public='false' Static='false' Strictfp='false' Synchronized='false' Transient='false' TypeInferred='false' VariableName='a' Volatile='false'>
                                    <Type Array='false' ArrayDepth='0' ArrayType='false' Image='' TypeImage='int'>
                                        <PrimitiveType Array='false' ArrayDepth='0' Boolean='false' Image='int' />
                                    </Type>
                                    <VariableDeclarator Image='' Initializer='true' Name='a'>
                                        <VariableDeclaratorId Array='false' ArrayDepth='0' ArrayType='false' ExceptionBlockParameter='false' ExplicitReceiverParameter='false' Field='false' Final='false' ForeachVariable='false' FormalParameter='false' Image='a' LambdaParameter='false' LocalVariable='true' Name='a' PatternBinding='false' ResourceDeclaration='false' TypeInferred='false' VariableName='a' />
                                        <VariableInitializer Image=''>
                                            <Expression Image='' StandAlonePrimitive='true'>
                                                <PrimaryExpression Image=''>
                                                    <PrimaryPrefix Image='' SuperModifier='false' ThisModifier='false'>
                                                        <Literal CharLiteral='false' DoubleLiteral='false' EscapedStringLiteral='1' FloatLiteral='false' Image='1' IntLiteral='true' LongLiteral='false' SingleCharacterStringLiteral='false' StringLiteral='false' TextBlock='false' TextBlockContent='1' ValueAsDouble='NaN' ValueAsFloat='NaN' ValueAsInt='1' ValueAsLong='1' />
                                                    </PrimaryPrefix>
                                                </PrimaryExpression>
                                            </Expression>
                                        </VariableInitializer>
                                    </VariableDeclarator>
                                </LocalVariableDeclaration>
                            </BlockStatement>
                            <BlockStatement Allocation='false' Image=''>
                                <Statement Image=''>
                                    <WhileStatement Image=''>
                                        <Expression Image='' StandAlonePrimitive='false'>
                                            <RelationalExpression Image='&amp;lt;'>
                                                <PrimaryExpression Image=''>
                                                    <PrimaryPrefix Image='' SuperModifier='false' ThisModifier='false'>
                                                        <Name Image='a' />
                                                    </PrimaryPrefix>
                                                </PrimaryExpression>
                                                <PrimaryExpression Image=''>
                                                    <PrimaryPrefix Image='' SuperModifier='false' ThisModifier='false'>
                                                        <Literal CharLiteral='false' DoubleLiteral='false' EscapedStringLiteral='10' FloatLiteral='false' Image='10' IntLiteral='true' LongLiteral='false' SingleCharacterStringLiteral='false' StringLiteral='false' TextBlock='false' TextBlockContent='10' ValueAsDouble='NaN' ValueAsFloat='NaN' ValueAsInt='10' ValueAsLong='10' />
                                                    </PrimaryPrefix>
                                                </PrimaryExpression>
                                            </RelationalExpression>
                                        </Expression>
                                        <Statement Image=''>
                                            <Block Image='' containsComment='false'>
                                                <BlockStatement Allocation='false' Image=''>
                                                    <Statement Image=''>
                                                        <StatementExpression Image=''>
                                                            <PostfixExpression Image='++' Operator='++'>
                                                                <PrimaryExpression Image=''>
                                                                    <PrimaryPrefix Image='' SuperModifier='false' ThisModifier='false'>
                                                                        <Name Image='a' />
                                                                    </PrimaryPrefix>
                                                                </PrimaryExpression>
                                                            </PostfixExpression>
                                                        </StatementExpression>
                                                    </Statement>
                                                </BlockStatement>
                                                <BlockStatement Allocation='false' Image=''>
                                                    <Statement Image=''>
                                                        <IfStatement Else='true' Image=''>
                                                            <Expression Image='' StandAlonePrimitive='false'>
                                                                <RelationalExpression Image='&amp;lt;'>
                                                                    <PrimaryExpression Image=''>
                                                                        <PrimaryPrefix Image='' SuperModifier='false' ThisModifier='false'>
                                                                            <Name Image='a' />
                                                                        </PrimaryPrefix>
                                                                    </PrimaryExpression>
                                                                    <PrimaryExpression Image=''>
                                                                        <PrimaryPrefix Image='' SuperModifier='false' ThisModifier='false'>
                                                                            <Literal CharLiteral='false' DoubleLiteral='false' EscapedStringLiteral='5' FloatLiteral='false' Image='5' IntLiteral='true' LongLiteral='false' SingleCharacterStringLiteral='false' StringLiteral='false' TextBlock='false' TextBlockContent='5' ValueAsDouble='NaN' ValueAsFloat='NaN' ValueAsInt='5' ValueAsLong='5' />
                                                                        </PrimaryPrefix>
                                                                    </PrimaryExpression>
                                                                </RelationalExpression>
                                                            </Expression>
                                                            <Statement Image=''>
                                                                <Block Image='' containsComment='false'>
                                                                    <BlockStatement Allocation='false' Image=''>
                                                                        <Statement Image=''>
                                                                            <StatementExpression Image=''>
                                                                                <PrimaryExpression Image=''>
                                                                                    <PrimaryPrefix Image='' SuperModifier='false' ThisModifier='false'>
                                                                                        <Name Image='System.out.println' />
                                                                                    </PrimaryPrefix>
                                                                                    <PrimarySuffix ArgumentCount='1' Arguments='true' ArrayDereference='false' Image=''>
                                                                                        <Arguments ArgumentCount='1' Image='' Size='1'>
                                                                                            <ArgumentList Image='' Size='1'>
                                                                                                <Expression Image='' StandAlonePrimitive='false'>
                                                                                                    <PrimaryExpression Image=''>
                                                                                                        <PrimaryPrefix Image='' SuperModifier='false' ThisModifier='false'>
                                                                                                            <Literal CharLiteral='false' DoubleLiteral='false' EscapedStringLiteral='"a&amp;lt;5"' FloatLiteral='false' Image='"a&amp;lt;5"' IntLiteral='false' LongLiteral='false' SingleCharacterStringLiteral='false' StringLiteral='true' TextBlock='false' TextBlockContent='"a&amp;lt;5"' ValueAsDouble='NaN' ValueAsFloat='NaN' ValueAsInt='0' ValueAsLong='0' />
                                                                                                        </PrimaryPrefix>
                                                                                                    </PrimaryExpression>
                                                                                                </Expression>
                                                                                            </ArgumentList>
                                                                                        </Arguments>
                                                                                    </PrimarySuffix>
                                                                                </PrimaryExpression>
                                                                            </StatementExpression>
                                                                        </Statement>
                                                                    </BlockStatement>
                                                                </Block>
                                                            </Statement>
                                                            <Statement Image=''>
                                                                <Block Image='' containsComment='false'>
                                                                    <BlockStatement Allocation='false' Image=''>
                                                                        <Statement Image=''>
                                                                            <StatementExpression Image=''>
                                                                                <PrimaryExpression Image=''>
                                                                                    <PrimaryPrefix Image='' SuperModifier='false' ThisModifier='false'>
                                                                                        <Name Image='System.out.println' />
                                                                                    </PrimaryPrefix>
                                                                                    <PrimarySuffix ArgumentCount='1' Arguments='true' ArrayDereference='false' Image=''>
                                                                                        <Arguments ArgumentCount='1' Image='' Size='1'>
                                                                                            <ArgumentList Image='' Size='1'>
                                                                                                <Expression Image='' StandAlonePrimitive='false'>
                                                                                                    <PrimaryExpression Image=''>
                                                                                                        <PrimaryPrefix Image='' SuperModifier='false' ThisModifier='false'>
                                                                                                            <Literal CharLiteral='false' DoubleLiteral='false' EscapedStringLiteral='"a>=5"' FloatLiteral='false' Image='"a>=5"' IntLiteral='false' LongLiteral='false' SingleCharacterStringLiteral='false' StringLiteral='true' TextBlock='false' TextBlockContent='"a>=5"' ValueAsDouble='NaN' ValueAsFloat='NaN' ValueAsInt='0' ValueAsLong='0' />
                                                                                                        </PrimaryPrefix>
                                                                                                    </PrimaryExpression>
                                                                                                </Expression>
                                                                                            </ArgumentList>
                                                                                        </Arguments>
                                                                                    </PrimarySuffix>
                                                                                </PrimaryExpression>
                                                                            </StatementExpression>
                                                                        </Statement>
                                                                    </BlockStatement>
                                                                </Block>
                                                            </Statement>
                                                        </IfStatement>
                                                    </Statement>
                                                </BlockStatement>
                                            </Block>
                                        </Statement>
                                    </WhileStatement>
                                </Statement>
                            </BlockStatement>
                        </Block>
                    </MethodDeclaration>
                </ClassOrInterfaceBodyDeclaration>
            </ClassOrInterfaceBody>
        </ClassOrInterfaceDeclaration>
    </TypeDeclaration>
</CompilationUnit>

编译

mvn clean compile

或者javac

class反编译字节码

(base) hogwarts: example seveniruby$ javap -v -l -s -c Main.class
Classfile /Users/seveniruby/ke/shift_left/java_demo2/target/classes/org/example/Main.class
  Last modified 2023年8月17日; size 639 bytes
  MD5 checksum 99b52f268dd2e7ecefc4d4131b8a77b0
  Compiled from "Main.java"
public class org.example.Main
  minor version: 0
  major version: 55
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #6                          // org/example/Main
  super_class: #7                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
   #1 = Methodref          #7.#24         // java/lang/Object."<init>":()V
   #2 = Fieldref           #25.#26        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = String             #27            // a<5
   #4 = Methodref          #28.#29        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = String             #30            // a>=5
   #6 = Class              #31            // org/example/Main
   #7 = Class              #32            // java/lang/Object
   #8 = Utf8               <init>
   #9 = Utf8               ()V
  #10 = Utf8               Code
  #11 = Utf8               LineNumberTable
  #12 = Utf8               LocalVariableTable
  #13 = Utf8               this
  #14 = Utf8               Lorg/example/Main;
  #15 = Utf8               main
  #16 = Utf8               ([Ljava/lang/String;)V
  #17 = Utf8               args
  #18 = Utf8               [Ljava/lang/String;
  #19 = Utf8               a
  #20 = Utf8               I
  #21 = Utf8               StackMapTable
  #22 = Utf8               SourceFile
  #23 = Utf8               Main.java
  #24 = NameAndType        #8:#9          // "<init>":()V
  #25 = Class              #33            // java/lang/System
  #26 = NameAndType        #34:#35        // out:Ljava/io/PrintStream;
  #27 = Utf8               a<5
  #28 = Class              #36            // java/io/PrintStream
  #29 = NameAndType        #37:#38        // println:(Ljava/lang/String;)V
  #30 = Utf8               a>=5
  #31 = Utf8               org/example/Main
  #32 = Utf8               java/lang/Object
  #33 = Utf8               java/lang/System
  #34 = Utf8               out
  #35 = Utf8               Ljava/io/PrintStream;
  #36 = Utf8               java/io/PrintStream
  #37 = Utf8               println
  #38 = Utf8               (Ljava/lang/String;)V
{
  public org.example.Main();
    descriptor: ()V
    flags: (0x0001) 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 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lorg/example/Main;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: iconst_1
         1: istore_1
         2: iload_1
         3: bipush        10
         5: if_icmpge     38
         8: iinc          1, 1
        11: iload_1
        12: iconst_5
        13: if_icmpge     27
        16: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        19: ldc           #3                  // String a<5
        21: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        24: goto          2
        27: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        30: ldc           #5                  // String a>=5
        32: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        35: goto          2
        38: return
      LineNumberTable:
        line 5: 0
        line 6: 2
        line 7: 8
        line 8: 11
        line 9: 16
        line 11: 27
        line 14: 38
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      39     0  args   [Ljava/lang/String;
            2      37     1     a   I
      StackMapTable: number_of_entries = 3
        frame_type = 252 /* append */
          offset_delta = 2
          locals = [ int ]
        frame_type = 24 /* same */
        frame_type = 10 /* same */
}
SourceFile: "Main.java"

jvm指令集

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html

UnsupportedClassVersionError

错误: 加载主类 org.sonarsource.scanner.cli.Main 时出现 LinkageError
java.lang.UnsupportedClassVersionError: org/sonarsource/scanner/cli/Main has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0

Class File Versions

JDK Version Bytecode Version
Java 1.0 45.0
Java 1.1 45.3
Java 1.2 46.0
Java 1.3 47.0
Java 1.4 48.0
Java 5 49.0
Java 6 50.0
Java 7 51.0
Java 8 52.0
Java 9 53.0
Java 10 54.0
Java 11 55.0
Java 12 56.0
Java 13 57.0
Java 14 58.0
Java 15 59.0
Java 16 60.0
Java 17 61.0
Java 18 62.0
Java 19 63.0
Java 20 64.0
Java 21 65.0
Java 22 66.0