Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method in companion object compiled into static methods in scala?

Tags:

scala

It looks like scala compiles methods in companion objects into static methods, which makes invoking them from java code a little easier. For example, you could write CompanionObject.method() instead of CompanionObject$.MODULE$.method(). However, sometimes seemingly irrelevant code change will break this behavior. I came up with this example to illustrate the problem

$ cat TestCompanion.scala 
class TestCompanion

object TestCompanion {
  def init2 {}
}

@SerialVersionUID(1L)
class TestCompanion2

object TestCompanion2 {
  def init2 {}
}


$ scalac -version
Scala compiler version 2.9.0.1 -- Copyright 2002-2011, LAMP/EPFL

$ scalac TestCompanion.scala
$ javap TestCompanion
Compiled from "TestCompanion.scala"
public class TestCompanion extends java.lang.Object implements scala.ScalaObject{
    public static final void init2();
    public TestCompanion();
}

$ javap TestCompanion2
Compiled from "TestCompanion.scala"
public class TestCompanion2 extends java.lang.Object implements scala.ScalaObject{
    public static final long serialVersionUID;
    public static {};
    public TestCompanion2();
}

So the only difference between TestCompanion and TestCompanion2 is that the latter is annotated with @SerialVersionUID, and init2 is compiled into a static method in TestCompanion but not in TestCompanion2.

Can someone explain why scalac treats these two classes differently? I don't see how the @SerialVersionUID annotation should affect the availability of static methods.

like image 733
user881423 Avatar asked Oct 28 '11 00:10

user881423


People also ask

How do I declare a static method in Scala?

In Scala there are no static methods: all methods are defined over an object, be it an instance of a class or a singleton, as the one you defined in your question.

Which of the following operations are provided by collection companion objects in Scala?

A companion object is an object that's declared in the same file as a class , and has the same name as the class. A companion object and its class can access each other's private members. A companion object's apply method lets you create new instances of a class without using the new keyword.

Does Scala support static methods?

Scala does not have static keyword, but still we can define them by using object keyword. The main design decision about this is that the clear separation between instance and static members.

What is the advantage of companion object in Scala?

Advantages of Companion Objects in Scala Companion objects provide a clear separation between static and non-static methods in a class because everything that is located inside a companion object is not a part of the class's runtime objects but is available from a static context and vice versa.


1 Answers

This is a known bug: Static forwarders are missing after adding @SerialVersionUID, raised by Josh Cough. From the description of the bug:

In the following code, adding @SerialVersionUID to the class results in the static forwarders missing from the byte code.

object WithoutUID {
 val instance = new WithoutUID
}
class WithoutUID extends scala.Serializable

object WithUID {
 val instance = new WithUID
}
@SerialVersionUID(0) 
class WithUID extends scala.Serializable

Here is the relevant decompiled byte code:

public class WithoutUID implements Serializable, ScalaObject {
  public static final WithoutUID instance(){
    return WithoutUID.MODULE$.instance();
  }
}

public class WithUID implements Serializable, ScalaObject {
  public static final long serialVersionUID = 0L;
}
like image 129
Matthew Farwell Avatar answered Sep 18 '22 04:09

Matthew Farwell