Viewing kotlin bytecode as Java for compiler generated classes

In IntelliJ there is a Kotlin Bytecode window that allows me to view jvm bytecode and to decompile Kotlin classes to Java. This is a great way to learn how kotlin compiler generates code, unfortunately there is no option to decompile classes that were generated for lambda expression closures.

For example given code:

fun main(args: Array<String>) {
    val numbers = arrayOf(1,2,3,4,5)

    var sum = 0
    numbers.forEachNonInline { sum += it }

    call {
        println("sum = $sum")
        sum = 101
    }

    println("sum = $sum")
}

fun <T> Array<T>.forEachNonInline(action: (T)->Unit) {
    for (element in this) {
        action(element)
    }
}

fun call(codeBlock: ()->Unit) {
    codeBlock()
}

Compiler generates two additional classes AppKt$main$1 and AppKt$main$2 (I can see them in JD-Java Decompiler and in Kotlin bytecode window), but I cannot decompile them to Java - only main class AppKt is decompiled.

Since JD is not the best decompiler to view Kotlin binaries, could you recommend any other tool that will allow me to comfortably view generated code as Java code?

After a bit of searching I found that FernFlower+Bytecode Viewer (as a GUI) pair works the best. Most of the decompilers cannot handle lambda or even this simple main method above. FernFlower correctly decompiles lambda classes.

Bytecode Viewer: Releases · Konloch/bytecode-viewer · GitHub

1 Like