Search code examples
scalareflectionclassname

Why does Scala place a dollar sign at the end of class names?


In Scala when you query an object for either its class or its class name, you'll get a rogue dollar sign ("$") at the tail end of the printout:

object DollarExample {
  def main(args : Array[String]) : Unit = {
    printClass()
  }

  def printClass() {
    println(s"The class is ${getClass}")
    println(s"The class name is ${getClass.getName}")
  }
}

This results with:

The class is class com.me.myorg.example.DollarExample$
The class name is com.me.myorg.example.DollarExample$

Sure, it's simple enough to manually remove the "$" at the end, but I'm wondering:

  • Why is it there?; and
  • Is there anyway to "configure Scala" to omit it?

Solution

  • What you are seeing here is caused by the fact that scalac compiles every object to two JVM classes. The one with the $ at the end is actually the real singleton class implementing the actual logic, possibly inheriting from other classes and/or traits. The one without the $ is a class containing static forwarder methods. That's mosty for Java interop's sake I assume. And also because you actually need a way to create static methods in scala, because if you want to run a program on the JVM, you need a public static void main(String[] args) method as an entry point.

    scala> :paste -raw
    // Entering paste mode (ctrl-D to finish)
    
    object Main { def main(args: Array[String]): Unit = ??? }
    
    // Exiting paste mode, now interpreting.
    
    
    scala> :javap -p -filter Main
    Compiled from "<pastie>"
    public final class Main {
      public static void main(java.lang.String[]);
    }
    
    scala> :javap -p -filter Main$
    Compiled from "<pastie>"
    public final class Main$ {
      public static Main$ MODULE$;
      public static {};
      public void main(java.lang.String[]);
      private Main$();
    }
    

    I don't think there's anything you can do about this.