I'm trying to inject some Scala code into my existing Java app. (So, being said, I want some more fun).
I create a singleton stuff in Scala
ScalaPower.scala
package org.fun
class ScalaPower
object ScalaPower{
def showMyPower(time:Int) = {
(0 to time-1).mkString(", ")
}
}
Now, inside OldJava.java
class OldJava {
public void demo(){
System.out.println(?)
}
}
What should I fill in ?
so that Java will call the showMyPower method?
I tried both org.fun.ScalaPower.showMyPower(10)
and org.fun.ScalaPower.getInstance().showMyPower(10)
but none work.
(Decompile the class file using Jad show me nothing but nonsense code.)
Edit
I remove the class ScalaPower
declaration and scala produce the static method as expected. (call to org.fun.ScalaPower.showMyPower(10)
just works).
Wonder if it's a bug in scala compiler or not
It's usually better to access the singleton directly from its own class.
In this case:
org.fun.ScalaPower$.MODULE$.showMyPower(10);
Without going too much into the implementation details, Scala differentiates namespaces between Object and Class/Trait. This means they can use the same name. However, an object has a class, and therefore needs a mangled name on the JVM. The current Scala conventions is to add a $ at the end of the module name (for top-level modules). If the object is defined in a class, I believe the convention is OuterClass$ModuleName$. To enforce the singleton property of the ScalaPower module, there is also a static MODULE$ member of the ModuleName$ class. This is initialised at class-load time, ensuring that there is only one instance. A side effect of this is that you should not do any sort of locking in a module's constructor.
In any case, Scala also has built into it a "make things nicer for Java" static-forwarders mechanism. This is where it writes static methods on the ScalaPower class that just call ScalaPower$.MODULE$.someMethod(). If you also define a companion class, the forwarders that could be generated are limited, as you are not allowed to have naming conflicts with static and instance-level methods on the JVM. I think in 2.8.0 this means if you have a companion object, you lose your static forwarders.
In this case a "best practice" would be to always use the ScalaPower$.MODULE$ reference instead of a static forwarder, as the forwarder could disappear with modifications to the ScalaPower class.
EDIT: Typo