What def, val, and var fields in Scala traits look like after they’re compiled (including the classes that extend them)
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
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.
As part of the illness stuff I went through in 2014-2016, I have absolutely no memory of creating this Scala/FP “I can’t believe I used a
var” image, but as I just ran across it while working on this website, I thought it was funny. Apparently I created it when I was writing about How to create outlined text using Gimp. (I do remember that someone else created an image of Martin Odersky with the same phrase.)
When I update the Scala Cookbook, I need to update Recipe 8.2, “How to use abstract and concrete fields in Scala traits.” That recipe is written particularly with an OOP developer in mind, and I didn’t write about handling the same situation from an FP perspective.
The main goals for this lesson are:
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?
“A variable is a named entity that refers to an object. A variable is either a
val or a
var. Both vals and vars must be initialized when defined, but only vars can be later reassigned to refer to a different object.”
This is an excerpt from my forthcoming book on Scala and Functional Programming. It’s an appendix that “explains and explores” Scala’s function syntax.
Sadly, I had to get away from Scala for a while, but now I can get back to it again. Just as I started getting back into it I happened upon the following code, and thought, “Well, surely
title in this anonymous class is a
var field. How strange that the Programming in Scala guys would use a
var like this.”:
This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 4.7, “How to prevent getter and setter methods from being generated in Scala classes.”
When you define a class field as a
var, Scala automatically generates getter and setter methods for the field, and defining a field as a
val automatically generates a getter method, but you don’t want either a getter or setter.
This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 4.2, “How to control the visibility of Scala class constructor fields.”
You want to control the visibility of fields that are used as constructor parameters in a Scala class.