jad

How to disassemble and decompile Scala code (javap, scalac, jad)

Table of Contents1 - Problem2 - Solution3 - Using javap4 - Using scalac print options5 - Use a decompiler6 - Discussion7 - See Also8 - Sponsored by ...

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 14.6, “How to disassemble and decompile Scala code.”

Back to top

Problem

In the process of learning Scala, or trying to understand a particular problem, you want to examine the source code and bytecode the Scala compiler generates from your original source code.

Back to top

Solution

You can use several different approaches to see how your Scala source code is translated:

What def, val, and var fields in Scala traits look like after they’re compiled (including the classes that extend them)

Table of Contents1 - def field in trait2 - val field in trait (abstract)3 - val field in trait (concrete)4 - var field in trait (abstract)5 - var field in trait (concrete)6 - An abstract class in the middle7 - A trait in the middle8 - Summary

I generally have a pretty good feel for how Scala traits work, and how they can be used for different needs. As one example, a few years ago I learned that it’s best to define abstract fields in traits using def. But there are still a few things I wonder about.

Today I had a few free moments and I decided to look at what happens under the covers when you use def, val, and var fields in traits, and then mix-in or extend those traits with classes. So I created some examples, compiled them with scalac -Xprint:all, and then decompiled them with JAD to see what everything looks like under the covers.

I was initially going to write a summary here, but if you want to know how things work under the hood, I think it helps to work through the examples, so for today I’ll leave that as an exercise for the reader.

A look at how the Scala `lazy val` syntax gets converted into Java code (bytecode)

Table of Contents1 - A little `lazy val` conversion example2 - A second `lazy val` conversion example3 - One more `lazy val` conversion example4 - The end

I don’t have any major conclusions to share in this blog post, but ... what I was curious about is how Scala implements “lazy val” fields. That is, when the Scala code I write is translated into a .class file and bytecode that a JVM can understand, what does that resulting code look like?