11

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?

0

2 Answers 2

24

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.

Sign up to request clarification or add additional context in comments.

2 Comments

This is cool, but it would need some comments to explain the purpose of the variable. For that reason, I've gone with the MODULE$ thing instead.
Agreed, cool and +1, but only works if you have write access to the Object's source. Will not work for scala.xml.TopScope, for example.
22
{ 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.

4 Comments

Some explanation would be good. Is this a 'portable' method, or are the $'s an implementation artifact of Scala ?
@Brian - I've partially answered in the edit. I'm not sure what you mean by 'portable' in contrast to 'implementation artifact'. It's both--Scala uses a consistent naming scheme for its implementation artifacts. Unlike anonymous closures, this one is easy to predict.
Given LocalEnvironment seems to be a standalone singleton object, it should probably be return LocalEnvironment.MODULE$ (no $ in LocalEnvironment).
@Fabian - That doesn't work. The LocalEnvironment class will contain exactly and only those static methods needed to copy the (non-static) methods in the Scala singleton. MODULE$ is not one of those methods--it is a field of the LocalEnvironment$ class that is instantiated in a single copy (i.e. LocalEnvironment$ is the class that contains implementation details, and MODULE$ is an implementation detail within it).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.