Jay Taylor's notes

back to listing index

Method in companion object compiled into static methods in scala? - Stack Overflow

[web search]
Original source (stackoverflow.com)
Tags: stackoverflow.com
Clipped on: 2012-08-09

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.

Image (Asset 1/2) alt=18.4k52855
asked Oct 28 '11 at 0:04
Image (Asset 2/2) alt=503

50% accept rate
  upvote
 flag
Same behaviour on 2.9.1 & 2.10.0.r25798-b20111007020214. Looks like a bug to me, or at least an inconsistency – Matthew Farwell Oct 28 '11 at 9:12
add comment

1 Answer

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

none

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

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

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

Here is the relevant decompiled byte code:

none
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;
}
answered Oct 28 '11 at 9:13
Matthew Farwell
18.4k52855
add comment

Your Answer

 
community wiki

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