Scala: How to define a private primary class constructor

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 4.4, “How to define a private primary constructor in Scala.”

Problem

You want to make the primary constructor of a Scala class private, such as to enforce the Singleton pattern.

Solution

To make the primary constructor private, insert the private keyword in between the class name and any parameters the constructor accepts:

// a private no-args primary constructor
class Order private { ...
            -------

// a private one-arg primary constructor
class Person private (name: String) { ...
             -------

As shown in the REPL, this keeps you from being able to create an instance of the class:

scala> class Person private (name: String)
defined class Person

scala> val p = new Person("Mercedes")
<console>:9: error: constructor Person in class Person cannot be accessed
in object $iw
       val p = new Person("Mercedes")
               ^

Discussion

A simple way to enforce the Singleton pattern in Scala is to make the primary constructor private, then put a getInstance method in the companion object of the class:

class Brain private {
    override def toString = "This is the brain."
}

object Brain {
    val brain = new Brain
    def getInstance = brain
}

object SingletonTest extends App {

    // this won't compile
    // val brain = new Brain

    // this works
    val brain = Brain.getInstance
    println(brain)
}

You don’t have to name the accessor method getInstance; it’s only used here because of the Java convention.

A companion object is simply an object that’s defined in the same file as a class, where the object and class have the same name. If you declare a class named Foo in a file named Foo.scala, and then declare an object named Foo in that same file, the Foo object is the companion object for the Foo class.

A companion object has several purposes, and one purpose is that any method declared in a companion object will appear to be a static method on the object. See Recipe 6.6 for more information on creating the equivalent of Java’s static methods, and Recipe 6.8 for examples of how (and why) to define apply methods in a companion object.

Utility classes

Depending on your needs, creating a private class constructor may not be necessary at all. For instance, in Java you’d create a file utilities class by defining static methods in a Java class, but in Scala you do the same thing by putting all the methods in a Scala object:

object FileUtils {
    def readFile(filename: String) = {
        // code here ...
    }
    def writeToFile(filename: String, contents: String) {
        // code here ...
    }
}

This lets consumers of your code call these methods like this:

val contents = FileUtils.readFile("input.txt")
FileUtils.writeToFile("output.txt", content)

Because only an object is defined, code like this won’t compile:

val utils = new FileUtils  // won't compile

So in this case, there’s no need for a private class constructor; just don’t define a class.