Inspecting Bytecode with javap
Decompile class files with javap -c to understand how Java constructs translate to bytecode.
Inspecting Bytecode with javap is a free Java Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Inspect Bytecode?
Understanding bytecode reveals how the JVM actually executes your Java code. It helps debug performance issues, understand compiler optimizations, and verify that synthetic code (lambdas, inner classes) works as expected.
Basic javap Usage
javap ClassName displays the class's public API (method signatures, field declarations). It reads the .class file from the current directory or classpath.
# Compile first:
javac User.java
# Display public API:
javap User
# Output:
# public class User {
# public java.lang.String getName();
# public int getAge();
# }Disassembling Bytecode with -c
javap -c User shows the JVM instruction set (opcodes) for each method. This is the core view for understanding execution flow.
# javap -c User
# public java.lang.String getName();
# Code:
# 0: aload_0
# 1: getfield #2 // Field name:Ljava/lang/String;
# 4: areturnVerbose Output with -v
javap -v User adds the constant pool, access flags, stack sizes, and exception table — essential for deep analysis and debugging ClassCastException.
# javap -v User
# Constant pool:
# #1 = Methodref #5.#22 // java/lang/Object."<init>":()V
# #2 = Fieldref #4.#23 // User.name:Ljava/lang/String;
# ...Common Bytecode Instructions
Know the most frequent opcodes: aload_0 (load this), getfield, putfield, invokevirtual, invokespecial (constructors/private), invokestatic, invokedynamic (lambdas), return, areturn.
Lambdas and invokedynamic
Lambda expressions compile to invokedynamic instructions. The first invocation uses LambdaMetafactory to generate a class; subsequent calls reuse it. javap -v shows the bootstrap method table.
// Java:
list.forEach(s -> System.out.println(s));
// Compiles to invokedynamic — javap shows:
// invokedynamic #4,0 // InvokeDynamic #0:accept:()Ljava/util/function/Consumer;String Concatenation Optimization
Modern javac uses invokedynamic for "Hello " + name instead of StringBuilder. javap -v shows the StringConcatFactory bootstrap method.
// Java 9+ string concat:
String s = "Hello " + name;
// Compiles to:
// invokedynamic #5,0 // InvokeDynamic #1:makeConcatWithConstantsSeeing Inner Class Access
When an outer class accesses a private field of an inner class (or vice versa), the compiler generates synthetic access$000 methods. javap -p (private members) reveals them.
# javap -p OuterClass
# static int access$000(OuterClass);
# -- synthetic bridge method generated by the compilerVerifying Autoboxing Cost
Autoboxing compiles to Integer.valueOf() or int.intValue() calls. Use javap -c to confirm boxing happens and decide whether to use primitives.
// Java:
List<Integer> list = new ArrayList<>();
list.add(42); // autoboxing
// Bytecode:
// bipush 42
// invokestatic java/lang/Integer.valueOf:(I)Ljava/lang/Integer;Reading Try-Catch from Bytecode
Exception handlers appear as entries in the exception table, visible with javap -v. Each entry shows the try-start, try-end, handler, and caught type.
# Exception table:
# from to target type
# 2 10 15 Class java/io/IOException
# -- means: if IOException in bytes 2-10, jump to handler at byte 15Class File Header
The class file header contains the magic number (CAFEBABE), major/minor version, and access flags. javap -v shows the major version, which maps to the Java release that compiled the class.
# javap -v User
# minor version: 0
# major version: 61 <- Java 17
# flags: ACC_PUBLIC, ACC_SUPERQuick Check
Which javap flag shows JVM opcodes for each method?
Recap
Use javap -c for opcodes and javap -v for full detail. Know key opcodes: invokevirtual, invokespecial, invokedynamic, getfield. Inspect lambdas, boxing, and string concat to understand compiler output.
Frequently asked questions
Is the “Inspecting Bytecode with javap” lesson free?
Yes — the full text of “Inspecting Bytecode with javap” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.
What will I learn in “Inspecting Bytecode with javap”?
Decompile class files with javap -c to understand how Java constructs translate to bytecode. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Java Academy?
No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Inspecting Bytecode with javap” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Java Academy lesson?
Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.