Module java.base

Class ClassPrinter

java.lang.Object
java.lang.classfile.components.ClassPrinter

public final class ClassPrinter extends Object
ClassPrinter is a preview API of the Java platform.
Programs can only use ClassPrinter when preview features are enabled.
Preview features may be removed in a future release, or upgraded to permanent features of the Java platform.
A printer of classfiles and its elements.

Any ClassModelPREVIEW, FieldModelPREVIEW, MethodModelPREVIEW, or CodeModelPREVIEW can be printed to a human-readable structured text in JSON, XML, or YAML format. Or it can be exported into a tree of traversable and printable nodes, more exactly into a tree of ClassPrinter.MapNodePREVIEW, ClassPrinter.ListNodePREVIEW, and ClassPrinter.LeafNodePREVIEW instances.

Level of details to print or to export is driven by ClassPrinter.VerbosityPREVIEW option.

Printing is for debugging purposes only. Printed text schema, tree content and structure not guaranteed. It may change anytime in a future.

The most frequent use case is to simply print a class:

ClassPrinter.toJson(classModel, ClassPrinter.Verbosity.TRACE_ALL, System.out::print);

ClassPrinterPREVIEW allows to traverse tree of simple printable nodes to hook custom printer:

void customPrint(ClassModel classModel) {
    print(ClassPrinter.toTree(classModel, ClassPrinter.Verbosity.TRACE_ALL));
}

void print(ClassPrinter.Node node) {
    switch (node) {
        case ClassPrinter.MapNode mn -> {
            // print map header
            mn.values().forEach(this::print);
        }
        case ClassPrinter.ListNode ln -> {
            // print list header
            ln.forEach(this::print);
        }
        case ClassPrinter.LeafNode n -> {
            // print leaf node
        }
    }
}

Another use case for ClassPrinterPREVIEW is to simplify writing of automated tests:

@Test
void printNodesInTest(ClassModel classModel) {
    var classNode = ClassPrinter.toTree(classModel, ClassPrinter.Verbosity.TRACE_ALL);
    assertContains(classNode, "method name", "myFooMethod");
    assertContains(classNode, "field name", "myBarField");
    assertContains(classNode, "inner class", "MyInnerFooClass");
}

void assertContains(ClassPrinter.Node node, ConstantDesc key, ConstantDesc value) {
    if (!node.walk().anyMatch(n -> n instanceof ClassPrinter.LeafNode ln
                           && ln.name().equals(key)
                           && ln.value().equals(value))) {
        node.toYaml(System.out::print);
        throw new AssertionError("expected %s: %s".formatted(key, value));
    }
}

Since:
22