Overview
javap prints the contents of compiled class files. Plain javap Foo shows the public
API; -c disassembles method bodies to bytecode; -v adds the constant pool, flags,
attributes and stack-map frames. It is the ground truth for "what did javac actually emit"
questions — desugaring, synthetic members, and invokedynamic call sites are all visible
here and nowhere in the source.
Key points
- Flags:
-c(bytecode),-v(verbose: constant pool + attributes),-p(include private members),-s(internal signatures/descriptors),-l(line/local tables). - Reading output: descriptors like
(Ljava/lang/String;I)V; the constant pool is a numbered table that instructions reference (#7);Code:blocks show operand-stack bytecode (aload_0,invokevirtual…). - String concatenation: since JEP 280,
+compiles to a singleinvokedynamiconStringConcatFactory— notStringBuilderchains; visible immediately with-c. - Records:
-vshows theRecordattribute, generated accessors, andequals/hashCode/toStringbootstrapped viaObjectMethodsinvokedynamic. - Switch desugaring: string switches become
hashCode+equalscascades overlookupswitch; pattern-matching switches bootstrap throughSwitchBootstraps.typeSwitchinvokedynamic. - Other uses: confirming a class file's major version (
-vheader) when chasingUnsupportedClassVersionError; inspecting synthetic bridge methods from generics; works on anything on the classpath, including JDK classes (javap -c java.lang.String).
Examples
javap -p -v -cp build/classes com.example.Point # a record, in full detail
javap -c HelloConcat | grep -A2 invokedynamic # see JEP 280 concat
Related
- The JDK, the JRE & their tools — parent catalog of the toolchain.
- javac — javap verifies its output; the pair closes the loop.
- jdeps — the other static class-file analyser, at dependency granularity.
- Deep dive Java — bytecode is the input to the JIT story told there.