55

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?

1

3 Answers 3

56

Here are a few reasons, which might be more or less compelling for you, depending on your own preferences:

  1. 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.

  2. 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. Writing object instead of class makes it a singleton and you're done.

  3. 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 method f and an object c of type C. Then you should call C.f, but Java allows you (albeit with a warning) to use c.f, which when you come from the Scala background doesn't really make any sense, because objects do not have a method f really.

  4. 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.

  5. 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.

4
  • 1
    I 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
  • 3
    None 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 simply invokeStatic. Apr 5, 2018 at 16:37
36

One more benefit is that objects can implement interfaces/traits, unlike static methods.

1
  • 10
    I 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.
    – dcastro
    May 11, 2015 at 23:19
5

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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.