我正在尝试将一些Scala代码注入到我现有的Java应用程序中。 (所以说,我想要更多乐趣)。
我在Scala中创建了一个单例东西
ScalaPower.scala
package org.fun
class ScalaPower
object ScalaPower{
def showMyPower(time:Int) = {
(0 to time-1).mkString(", ")
}
}
现在,在OldJava.java中
class OldJava {
public void demo(){
System.out.println(?)
}
}
我应该填写?
,以便Java调用showMyPower方法?
我尝试了org.fun.ScalaPower.showMyPower(10)
和org.fun.ScalaPower.getInstance().showMyPower(10)
但都没有效果。
(使用Jad反编译类文件只显示无意义的代码。)
修改
我删除class ScalaPower
声明,scala按预期生成静态方法。 (致org.fun.ScalaPower.showMyPower(10)
只是有效)。
不知道它是否是scala编译器中的错误
答案 0 :(得分:17)
通常最好直接从自己的类中访问单例。
在这种情况下:
org.fun.ScalaPower$.MODULE$.showMyPower(10);
不会过多地介绍实现细节,Scala会区分Object和Class / Trait之间的名称空间。这意味着他们可以使用相同的名称。但是,对象具有类,因此需要JVM上的错位名称。当前的Scala约定是在模块名称末尾添加$(对于顶级模块)。如果对象是在类中定义的,我相信约定是OuterClass $ ModuleName $。要强制执行ScalaPower模块的单例属性,还有一个ModuleName $类的静态MODULE $成员。这是在类加载时初始化的,确保只有一个实例。这样做的副作用是你应该不在模块的构造函数中进行任何类型的锁定。
无论如何,Scala还内置了“为Java制作更好的”静态转发器机制。这是它在ScalaPower类上编写静态方法的地方,它只调用ScalaPower $ .MODULE $ .someMethod()。如果还定义了伴随类,则可以生成的转发器是有限的,因为不允许在JVM上与静态和实例级方法发生命名冲突。我认为在2.8.0中这意味着如果你有一个伴侣对象,你就会失去静态转发器。
在这种情况下,“最佳实践”是始终使用ScalaPower $ .MODULE $引用而不是静态转发器,因为转发器可能会随着ScalaPower类的修改而消失。
编辑:错字
答案 1 :(得分:10)
你得到的错误是什么? 使用Scala示例和以下Java类:
cat test.java
:
import org.fun.*;
public class test {
public static void main(String args[]) {
System.out.println("show my power: " + ScalaPower.showMyPower(3));
}
}
按以下方式运行:
java -cp .:<path-to/scala/install-dir>/lib/scala-library.jar test
给出了我的输出:
show my power: 0, 1, 2
答案 2 :(得分:9)
我认为这间接涵盖了它:
伴随对象和Java静态 方法
还有一件事需要了解 伴侣物体。每当你定义 用作条目的主要方法 对于一个应用程序,Scala 要求你把它放在一个对象中。 但是,在撰写本文时, 主要方法无法在a中定义 伴侣对象。因为 实施细节 生成代码后,JVM就找不到了 主要方法。这个问题可能是 在将来的版本中解决。目前, 你必须在a中定义任何main方法 单身对象(即a “非伴侣”对象)[ScalaTips]。 考虑以下a的例子 简单的Person类和伴侣 尝试定义main的对象。
在此处找到:http://programming-scala.labs.oreilly.com/ch06.html
简而言之,因为你的Object是一个伴侣对象(有一个伴侣类)你不能像你期望的那样调用它。正如你发现的那样,如果你摆脱了这个课程,那就可以了。
答案 3 :(得分:3)
请记住,库存javap
工具可用于查看Scala编译器生成的内容。当然,它并没有直接回答你的问题,但是当你需要的只是提醒代码生成模式时,它就足够了。
答案 4 :(得分:1)
完成后
class ScalaPower
object ScalaPower{
def showMyPower(time:Int) = {
(0 to time-1).mkString(", ")
}
}
ScalaPower.showMyPower(10)
按预期工作。