Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass a Scala object reference around in Java?

I want to return from a Java method a reference to a Scala object. How can I do that?

My Scala objects are like this:

trait Environment 

object LocalEnvironment extends Environment {...}
object ServerEnvironment extends Environment {...}

... and I want my Java method to be like this:

Environment getEnvironment() { return LocalEnvironment; }  // DOES NOT COMPILE

Is there a way to do this?

like image 904
David Avatar asked Oct 02 '10 12:10

David


2 Answers

While the $.MODULE$ method works, a slightly less jarring way to get Java-interop with Scala objects is to expose the object as a method on itself.

The Scala:

object LocalEnvironment extends Environment{
   def instance = this
}

The Java:

Environment getEnvironment() { return LocalEnvironment.instance(); }  

This works because under the covers, .instance() is implemented as a static method on class LocalEnvironment. There has been some discussion about Scala objects getting an "instance" method by default, for just this purpose.

like image 142
Dave Griffith Avatar answered Oct 05 '22 11:10

Dave Griffith


{ return LocalEnvironment$.MODULE$; }

should work.


Edit: the reason why this works is that this is how Scala represents singleton objects. The class ObjectName$ has a field in it called MODULE$ that is populated with the single valid instance of that class. But there is also a class called ObjectName that copies all the methods as static methods. That way you can use it like Java (just call ObjectName.methodName) in most cases, and Scala gets to have a real class to pass around.

But when Java needs to pass the class around--not something normally done with a bunch of static methods, which is what object is designed to emulate in Java--you then have to know how Scala represents it internally.

like image 29
Rex Kerr Avatar answered Oct 05 '22 10:10

Rex Kerr