Scala has no static-keyword, but instead has similar functionality through companion objects. Behind the scenes the companion objects are compiled to classes that have static methods, so all this is syntactic sugar. What are the advantages of this design choice? Disadvantages? Do other languanges have similar constructs?
3 Answers
Here are a few reasons, which might be more or less compelling for you, depending on your own preferences:
Do not simply discount it for being "syntactic sugar". While you may say that something is just syntactic sugar, it is after all the sugar that sweetens your life - as a programmer just as well as a coffee or tea drinker.
Singletons - every Scala
object
is inherently a singleton. Considering that in the Java world people are implementing singletons in all sorts of different ways and more often than not end up making some mistake in their implementation, you cannot make an error as simple like that in Scala. Writingobject
instead ofclass
makes it a singleton and you're done.Access to static methods: The static methods in Java can be accessed from objects. For example, suppose you have a class
C
with a static methodf
and an objectc
of typeC
. Then you should callC.f
, but Java allows you (albeit with a warning) to usec.f
, which when you come from the Scala background doesn't really make any sense, because objects do not have a methodf
really.Clear separation: In Java you can mix static and non-static attributes and methods in a class. If you work disciplined, this doesn't become a problem, however, if you (or someone else for that matter) do not, then you end up with static and non-static parts interleaved and it is hard to tell at a quick glance what's static and what's not. In Scala, everything that's located inside the companion object is cleary not part of the corresponding class's runtime objects, but is available from a static context. Vice versa, if it is written inside a class, it is available to instances of that class, but not from a static context. This becomes especially burdensome in Java, once you start adding static and non-static initializer blocks to your class. This can end up to be very hard to comprehend in terms of dynamic execution order. It's a lot clearer in Scala, where you initialize the companion object from top to bottom and then do the same for the class in case of a runtime object being created.
Less code: You don't need to add the word static to each and every attribute or method in an
object
, thus keeping the code more concise (indeed, not a prominent advantage really).
Disadvantages are much harder to find. One might argue, that the static and non-static parts should belong together, but are separated by the Scala concept of companion objects. For example, it may appear strange to have a class diagram, but then end up having to create two things in the code and dissect which attribute goes where.
-
1I also read, that statics don't belong in a pure OOP software. Like, when you need static behavior, use a own class and create one (singleton) object of it, which manages the (potentially) static behaviour of the objects of another class.– K..Dec 14, 2012 at 15:03
-
1"Writing object instead of class makes it a singleton and you're done." I don't much care for Singletons myself, but I've got to admit that the directness of this particular "syntactic sugar" has a certain charm. Dec 20, 2012 at 20:10
-
3None of the points from 1 to 5 (and even all of them together) needs a true companion object at runtime to be implemented. All of them could be easily made to be pure syntactic sugar, with zero runtime impact. The only real reason to have runtime companion object is given in Alexey Romanov's answer. Jan 2, 2016 at 23:34
-
"Disadvantages are much harder to find." Performance? accessing an object method generates
ifnonnull
etc bytecode, compared with simplyinvokeStatic
. Apr 5, 2018 at 16:37
One more benefit is that object
s can implement interfaces/traits, unlike static methods.
-
10I think this is the major difference between a companion object vs a class with static methods. A companion object is polymorphic and can be passed around as an argument to methods that expect an interface/trait.– dcastroMay 11, 2015 at 23:19
Companion objects are the first place searched for implicits, after that, scala looks at Predef and then in explicit "import" statements in that particular source file.
I'm not enough of a java dev to know whether the java language or libraries provide any comparable mechanism.