Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: Trait Companion Object is not visible in Java

Tags:

java

scala

A companion object for a trait in Scala has no visibility problems in Scala:

trait ProtocolPacket extends Serializable {    
  def toByteArray: Array[Byte]
}

object ProtocolPacket {
  def getStreamType( streamBytes: Array[Byte] ) = {
    // ...
  }
}

However on Java side (e.g. gets the above in a jar), a ProtocolPacket.getStreamType is not visible. In fact a (decompiled by IDEA) source does not have a getStreamType method defined for a ProtocolPacket

EDIT:

I found similar hits on SO regarding Companion$MODULE$, but was tricked by IDEA :) as shown below:

enter image description here

The above compiles and runs fine (shell and/or IDEA itself), in case anybody else gets trapped.

like image 415
tolitius Avatar asked Feb 24 '12 18:02

tolitius


People also ask

What is scala trait in Java?

scala is compiled into Trait interface. Hence implementing Trait in Java is interpreted as implementing an interface - which makes your error messages obvious.

What is a scala companion object?

A companion object in Scala is an object that's declared in the same file as a class , and has the same name as the class. For instance, when the following code is saved in a file named Pizza.scala, the Pizza object is considered to be a companion object to the Pizza class: class Pizza { } object Pizza { }

Can we create object of trait in scala?

Traits are similar in spirit to interfaces in Java programming language. Unlike a class, Scala traits cannot be instantiated and have no arguments or parameters.

Is companion object singleton in scala?

In scala, when you have a class with same name as singleton object, it is called companion class and the singleton object is called companion object. The companion class and its companion object both must be defined in the same source file.


2 Answers

Looking at javap output you will find:

$ javap ProtocolPacket
public interface ProtocolPacket extends scala.Serializable{
    public abstract byte[] toByteArray();
}

and companion object:

$ javap ProtocolPacket$
public final class ProtocolPacket$ extends java.lang.Object implements scala.ScalaObject,scala.Serializable{
    public static final ProtocolPacket$ MODULE$;
    public static {};
    public void getStreamType(byte[]);
    public java.lang.Object readResolve();
}

this makes me believe in Java you can write:

ProtocolPacket$.MODULE$.getStreamType(/**/)
like image 183
Tomasz Nurkiewicz Avatar answered Oct 21 '22 01:10

Tomasz Nurkiewicz


I think it's ProtocolPacket$.MODULE$.getStreamType() in Java but I haven't double checked.

See also How do you call a Scala singleton method from Java?.

like image 25
smparkes Avatar answered Oct 21 '22 01:10

smparkes