Java utility javap example

The JDK comes with a number of useful utilities located in the bin tools directory. For those who want to decompile bytecode, special interest presents Java utility javap

Command line utility javap, also known as the Java Class File Disassembler, outputs relevant information about any compiled Java class that is asked to test. By default, it just prints out the names of all non-private methods and variables declared in the class:

C:_toolsjava8javap examplebin>javap com.mcnz.javap.example.CommandTutorial
Compiled from "CommandTutorial.java"
public class com.mcnz.javap.example.CommandTutorial extends java.util.ArrayList<java.lang.Object> {
protected static java.lang.String foo;
public java.lang.String bar;
public com.mcnz.javap.example.CommandTutorial();
void doStuff();
public static void main(java.lang.String[]);
public void useInnerType();
}

Javap class file disassembler

Admittedly, the above uninteresting output is generated by the utility javap to check the bytecode generated when the class is compiled CommandTutorial below. Note that the class has many variables and methods with many access modifiers. The default JDK utility javap only displays information about non-private fields, although the flag -private allows you to provide information about private members.

package com.mcnz.javap.example;
import java.util.ArrayList;

public class CommandTutorial extends ArrayList<Object> {

  private static final long serialVersionUID = 1L;
  protected static String foo;
  public String bar;

  void doStuff() { }
  private String doStringStuff() { return null; }

  public static void main(String args[]) {
    class InnerClass {
      public String stringStuff() {return "";};
    }
  }

  interface InnerType { public void singleMethod(); };

  public void useInnerType() {
    InnerType innerTypeImpl = () -> System.out.println("javap example!");
  }
}

Popular javap command options

Utility output javap on default not particularly interesting… However, there are many flags that can be used to display much more interesting information. Popular command options and flags javap include:

  • -l will print tables of local variables for a class

  • -s will print the internal types of the class signature

  • -sysinfo will display last update date, MD5 hash, path and class size information

  • -verbose prints out a lot of information about the stack size, the number of arguments and local variables for methods, as well as a lot of information about the structure of the class.

  • -c forces the javap utility to print out the Java bytecode instructions by effectively disassembling the class

The javap utility has several options.  The javap command with the sysinfo switch shows the hash and information about the latest update.
The javap utility has several options. The javap command with the sysinfo switch shows the hash and information about the latest update.

How to use javap command

Most users of the utility javap interested in decompiling the class and viewing the disassembled bytecode. Here’s how to use the utility javap to view instruction bytecode:

  1. Make sure the utility javap are located along the path in the PATH variable of the operating system.

  2. Make sure the class to check javap compiled

  3. Enter the command javap with the -c option along with the class name

  4. View the instruction bytecode of the decompiled class

Decompiled Java Bytecode

Here is the result of decompiling the above class using the Java javap tool.

C:_toolsjava8javap examplebin> javap -verbose com.mcnz.javap.example.CommandTutorial

Classfile /C:/_tools/java8/javap example/bin/com/mcnz/javap/example/CommandTutorial.class
  Last modified Nov 25, 2021; size 1864 bytes
  MD5 checksum f1239fdfb14b9d5874f157242d884ea7
  Compiled from "CommandTutorial.java"
public class com.mcnz.javap.example.CommandTutorial extends java.util.ArrayList<java.lang.Object>
  minor version: 0
  major version: 55
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #1                          // com/mcnz/javap/example/CommandTutorial
  super_class: #3                         // java/util/ArrayList
  interfaces: 0, fields: 3, methods: 6, attributes: 5
Constant pool:
   #1 = Class              #2             // com/mcnz/javap/example/CommandTutorial
   #2 = Utf8               com/mcnz/javap/example/CommandTutorial
   #3 = Class              #4             // java/util/ArrayList
   #4 = Utf8               java/util/ArrayList
   #5 = Utf8               serialVersionUID
   #6 = Utf8               J
   #7 = Utf8               ConstantValue
   #8 = Long               1l
  #10 = Utf8               foo
  #11 = Utf8               Ljava/lang/String;
  #12 = Utf8               bar
  #13 = Utf8               <init>
  #14 = Utf8               ()V
  #15 = Utf8               Code
  #16 = Methodref          #3.#17         // java/util/ArrayList."<init>":()V
  #17 = NameAndType        #13:#14        // "<init>":()V
  #18 = Utf8               LineNumberTable
  #19 = Utf8               LocalVariableTable
  #20 = Utf8               this
  #21 = Utf8               Lcom/mcnz/javap/example/CommandTutorial;
  #22 = Utf8               doStuff
  #23 = Utf8               doStringStuff
  #24 = Utf8               ()Ljava/lang/String;
  #25 = Utf8               main
  #26 = Utf8               ([Ljava/lang/String;)V
  #27 = Utf8               args
  #28 = Utf8               [Ljava/lang/String;
  #29 = Utf8               useInnerType
  #30 = InvokeDynamic      #0:#31         // #0:singleMethod:()Lcom/mcnz/javap/example/CommandTutorial$InnerType;
  #31 = NameAndType        #32:#33        // singleMethod:()Lcom/mcnz/javap/example/CommandTutorial$InnerType;
  #32 = Utf8               singleMethod
  #33 = Utf8               ()Lcom/mcnz/javap/example/CommandTutorial$InnerType;
  #34 = Utf8               innerTypeImpl
  #35 = Utf8               Lcom/mcnz/javap/example/CommandTutorial$InnerType;
  #36 = Utf8               lambda$0
  #37 = Fieldref           #38.#40        // java/lang/System.out:Ljava/io/PrintStream;
  #38 = Class              #39            // java/lang/System
  #39 = Utf8               java/lang/System
  #40 = NameAndType        #41:#42        // out:Ljava/io/PrintStream;
  #41 = Utf8               out
  #42 = Utf8               Ljava/io/PrintStream;
  #43 = String             #44            // javap example!
  #44 = Utf8               javap example!
  #45 = Methodref          #46.#48        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #46 = Class              #47            // java/io/PrintStream
  #47 = Utf8               java/io/PrintStream
  #48 = NameAndType        #49:#50        // println:(Ljava/lang/String;)V
  #49 = Utf8               println
  #50 = Utf8               (Ljava/lang/String;)V
  #51 = Utf8               SourceFile
  #52 = Utf8               CommandTutorial.java
  #53 = Utf8               Signature
  #54 = Utf8               Ljava/util/ArrayList<Ljava/lang/Object;>;
  #55 = Utf8               BootstrapMethods
  #56 = Methodref          #57.#59        // java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljav
a/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #57 = Class              #58            // java/lang/invoke/LambdaMetafactory
  #58 = Utf8               java/lang/invoke/LambdaMetafactory
  #59 = NameAndType        #60:#61        // metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang
/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #60 = Utf8               metafactory
  #61 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lan
g/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #62 = MethodHandle       6:#56          // REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invok
e/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #63 = MethodType         #14            //  ()V
  #64 = Methodref          #1.#65         // com/mcnz/javap/example/CommandTutorial.lambda$0:()V
  #65 = NameAndType        #36:#14        // lambda$0:()V
  #66 = MethodHandle       6:#64          // REF_invokeStatic com/mcnz/javap/example/CommandTutorial.lambda$0:()V
  #67 = MethodType         #14            //  ()V
  #68 = Utf8               InnerClasses
  #69 = Class              #70            // com/mcnz/javap/example/CommandTutorial$1InnerClass
  #70 = Utf8               com/mcnz/javap/example/CommandTutorial$1InnerClass
  #71 = Utf8               InnerClass
  #72 = Class              #73            // com/mcnz/javap/example/CommandTutorial$InnerType
  #73 = Utf8               com/mcnz/javap/example/CommandTutorial$InnerType
  #74 = Utf8               InnerType
  #75 = Class              #76            // java/lang/invoke/MethodHandles$Lookup
  #76 = Utf8               java/lang/invoke/MethodHandles$Lookup
  #77 = Class              #78            // java/lang/invoke/MethodHandles
  #78 = Utf8               java/lang/invoke/MethodHandles
  #79 = Utf8               Lookup
  #80 = Utf8               NestMembers
{
  protected static java.lang.String foo;
    descriptor: Ljava/lang/String;
    flags: (0x000c) ACC_PROTECTED, ACC_STATIC

  public java.lang.String bar;
    descriptor: Ljava/lang/String;
    flags: (0x0001) ACC_PUBLIC

  public com.mcnz.javap.example.CommandTutorial();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #16                 // Method java/util/ArrayList."<init>":()V
         4: return
      LineNumberTable:
        line 5: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/mcnz/javap/example/CommandTutorial;

  void doStuff();
    descriptor: ()V
    flags: (0x0000)
    Code:
      stack=0, locals=1, args_size=1
         0: return
      LineNumberTable:
        line 11: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       1     0  this   Lcom/mcnz/javap/example/CommandTutorial;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=0, locals=1, args_size=1
         0: return
      LineNumberTable:
        line 19: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       1     0  args   [Ljava/lang/String;

  public void useInnerType();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=1
         0: invokedynamic #30,  0             // InvokeDynamic #0:singleMethod:()Lcom/mcnz/javap/example/CommandTutorial$InnerType;
         5: astore_1
         6: return
      LineNumberTable:
        line 26: 0
        line 27: 6
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       7     0  this   Lcom/mcnz/javap/example/CommandTutorial;
            6       1     1 innerTypeImpl   Lcom/mcnz/javap/example/CommandTutorial$InnerType;
}
SourceFile: "CommandTutorial.java"
Signature: #54                          // Ljava/util/ArrayList<Ljava/lang/Object;>;
BootstrapMethods:
  0: #62 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/Metho
      stack=0, locals=1, args_size=1
         0: return
      LineNumberTable:
        Start  Length  Slot  Name   Signature
            0       1     0  args   [Ljava/lang/String;

  public void useInnerType();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=1
         0: invokedynamic #30,  0             // InvokeDynamic #0:singleMethod:()Lcom/mcnz/javap/example/CommandTutorial$InnerType;
         5: astore_1
         6: return
      LineNumberTable:
        line 26: 0
        line 27: 6
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       7     0  this   Lcom/mcnz/javap/example/CommandTutorial;
            6       1     1 innerTypeImpl   Lcom/mcnz/javap/example/CommandTutorial$InnerType;
}
SourceFile: "CommandTutorial.java"
Signature: #54                          // Ljava/util/ArrayList<Ljava/lang/Object;>;
BootstrapMethods:
  0: #62 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/Metho
dType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #63 ()V
        line 19: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       1     0  args   [Ljava/lang/String;

  public void useInnerType();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=1
         0: invokedynamic #30,  0             // InvokeDynamic #0:singleMethod:()Lcom/mcnz/javap/example/CommandTutorial$InnerType;
         5: astore_1
         6: return
      LineNumberTable:
        line 26: 0
        line 27: 6
      LocalVariableTable:

        Start  Length  Slot  Name   Signature
            0       7     0  this   Lcom/mcnz/javap/example/CommandTutorial;
            6       1     1 innerTypeImpl   Lcom/mcnz/javap/example/CommandTutorial$InnerType;
}
SourceFile: "CommandTutorial.java"
Signature: #54                          // Ljava/util/ArrayList<Ljava/lang/Object;>;
BootstrapMethods:
  0: #62 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang
/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #63 ()V
      #66 REF_invokeStatic com/mcnz/javap/example/CommandTutorial.lambda$0:()V
      #67 ()V
InnerClasses:
  #71= #69;                               // InnerClass=class com/mcnz/javap/example/CommandTutorial$1InnerClass
  static #74= #72 of #1;                  // InnerType=class com/mcnz/javap/example/CommandTutorial$InnerType of class com/mcnz/javap/example
/CommandTutorial
  public static final #79= #75 of #77;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
NestMembers:
  com/mcnz/javap/example/CommandTutorial$1InnerClass
  com/mcnz/javap/example/CommandTutorial$InnerType

C:_toolsjava8javap examplebin>javap -c com.mcnz.javap.example.CommandTutorial
Compiled from "CommandTutorial.java"
public class com.mcnz.javap.example.CommandTutorial extends java.util.ArrayList<java.lang.Object> {
  protected static java.lang.String foo;

  public java.lang.String bar;

  public com.mcnz.javap.example.CommandTutorial();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/util/ArrayList."<init>":()V
       4: return

  void doStuff();
    Code:
       0: return

  public static void main(java.lang.String[]);
    Code:
       0: return

  public void useInnerType();
    Code:
       0: invokedynamic #30,  0             // InvokeDynamic #0:singleMethod:()Lcom/mcnz/javap/example/CommandTutorial$InnerType;
       5: astore_1
       6: return
}

Command execution results javap are detailed and extensive. For those who are interested in looking at some of the internal mechanisms Compiled Java Bytecode Utility javap is the right team.

Similar Posts

Leave a Reply