Java’s javap tool example

When you install Java, the JDK comes with a number of helpful utilities packed within the toolkit’s bin directory. For those who wish to inspect or disassemble compiled class files, the Java’s javap command will be of special interest.

Also known as the Java class file disassembler, the command-line javap tool will output pertinent information about any compiled Java class it is asked to inspect. By default, it simply spits out the names of all of the non-private methods and variables declared within a class:

C:\_tools\java8\javap example\bin>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();



}

The javap class file disassembler

The admittedly unexciting output above is generated by having the javap tool inspect the bytecode generated by the compilation the CommandTutorial class below. Note how the class has a variety of variables and methods with a variety of access modifiers. By default, the JDK’s javap tool will only output information about non-private fields, although the -private flag will provide information about private items as well.

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

The default output of the javap tool isn’t particularly exciting. However, there are a variety of flags that can be used to output decidedly more interesting information. Popular javap command options and flags include:

  • -l will print out the local variable tables for the class
  • -s will print internal type signatures of the class
  • -sysinfo will display the last update date, class-file checksum, path and size information about the class
  • -verbose prints out extensive information about stack size, the number of arguments and locals for methods, along with a great deal of information about how the class is structured
  • -c gets the javap tool to print out Java bytecode instructions, effectively disassembling the class
javap command tool example

The javap tool has a number of options. The javap command with the sysinfo switch shows hash and last update information.

How to use the javap command

Many users of the javap tool are interested in disassembling a class and viewing its bytecode instructions. Here’s how to use the javap tool to view bytecode instructions:

  1. Make sure the javap tool is on the PATH of the operating system
  2. Make sure the class to be inspected by javap is compiled
  3. Issue the javap command with the -c option along with the name of the class
  4. View the bytecode instructions of the decompiled class

Decompiled Java bytecode

Here is the result of disassembling the above class with Java’s javap tool.

C:\_tools\java8\javap example\bin> 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:\_tools\java8\javap example\bin>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



}

javap command example

The results of running the javap command are both verbose and extensive. But for those who are interested in looking at some of the inner workings of compiled bytecode in a Java installation, the javap utility is the right command to use.


Cameron McKenzie Cameron McKenzie is an AWS Certified AI Practitioner, Machine Learning Engineer, Solutions Architect and author of many popular books in the software development and Cloud Computing space. His growing YouTube channel training devs in Java, Spring, AI and ML has well over 30,000 subscribers.