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
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:
Make sure the utility javap are located along the path in the PATH variable of the operating system.
Make sure the class to check javap compiled
Enter the command javap with the -c option along with the class name
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.