For those moving from Java to Scala would find it a bit different to see how the classes and their fields are treated in Scala. Most of you in the Java world always complain about the verbosity of adding fields and then to add their getters and setters. Lets look at how the Classes and its fields in Scala are different from that in Java and how they map to the byte code consumed by the JVM.
also read:
We all should know that Scala is like one of the many languages which run on the Java Virtual Machine (JVM). Like Java, Scala is also a statically and strongly typed language. Any code written in Scala gets compiled into the byte code and if then executed by the JVM, so whatever syntactic sugar and constructs Scala provides it all ultimately boils down to creating byte code which can be executed by the JVM.
Before we dive into for more details one can read about installing scala plugin in Netbeans and also a basic article about scala.
Classes and Fields in Scala
Let’s take a very simple example of a class in Scala with one field:
class Person{ var name = "" }
Very concise! But we, the Java developers, would shout at this saying this breaks the encapsulation. Yes, but Scala automatically adds the getters and setters for the fields declared with a var keyword. Lets compile the above class and inspect the byte code using javap
~/scalaP$ scalac Person.scala ~/scalaP$ javap Person.class Compiled from "Person.scala" public class Person implements scala.ScalaObject { public java.lang.String name(); public void name_$eq(java.lang.String); public Person(); }
Looking at the above class file generated we can conclude that scala compiler adds getters and setters for the field declared as var. The getters are of the form fieldName() and the setters are of form fieldName_=. As java doesn’t allow the use of = in the method name, $eq is used instead. Lets go ahead and create an instance of this class:
object Person{ def main(args: Array[String]){ var person = new Person person.name = "Sanaulla" println(person.name) } } //Output: Sanaulla
One can provide their own getters and setters implementation. By declaring the name field in Person class as private, the compiler doesn’t generate any getters and setters.
class Person{ private var privateName = "" def name_=(n:String){ if ( n.length < 5){ println("name cannot be so small") } else{ privateName = n } } def name = privateName }
let’s use the above class definition and see how the getters and setters work:
object Person{ def main(args: Array[String]){ var person = new Person person.name = "Sanaulla" println(person.name) person.name = "Sana" println(person.name) } } //Output: //~/scalaP$ scala Person //Sanaulla //name cannot be so small //Sanaulla
A variable can declared as var or a val. Variables declared as var can be reassigned where as those declared as val cannot be. Read here for more details on their difference. Lets make the name field in the above Person class to val and see the class file generated:
class Person{ val name = "First name" }
The class file generated gives me only a getter and no setter which is obvious for a field which cannot be reassigned.
~/scalaP$ scalac Person.scala ~/scalaP$ javap Person.class Compiled from "Person.scala" public class Person implements scala.ScalaObject { public java.lang.String name(); public Person(); }
There are 2 more concepts related to fields- object private and bean properties which will be explored in subsequent posts.