你如何从Java调用Scala单例方法?

Phư*_*yễn 22 java interop scala scala-java-interop

我正在尝试将一些Scala代码注入到我现有的Java应用程序中.(所以说,我想要更多的乐趣).

我在Scala中创建了一个单例东西

ScalaPower.scala

    package org.fun
    class ScalaPower
    object ScalaPower{
      def showMyPower(time:Int) = {
        (0 to time-1).mkString(", ")
      }
    }
Run Code Online (Sandbox Code Playgroud)

现在,在OldJava.java中

class OldJava {
  public void demo(){
    System.out.println(?)
  }
}
Run Code Online (Sandbox Code Playgroud)

我应该填写什么?以便Java将调用showMyPower方法?我都尝试 org.fun.ScalaPower.showMyPower(10)org.fun.ScalaPower.getInstance().showMyPower(10)但没有工作.

(使用Jad反编译类文件只显示无意义的代码.)

编辑 我删除class ScalaPower声明和scala按预期生成静态方法.(打电话给org.fun.ScalaPower.showMyPower(10)工作).

不知道它是否是scala编译器中的错误

jsu*_*eth 17

通常最好直接从自己的类访问单例.

在这种情况下:

org.fun.ScalaPower$.MODULE$.showMyPower(10);
Run Code Online (Sandbox Code Playgroud)

在不过多介绍实现细节的情况下,Scala可以区分Object和Class/Trait之间的名称空间.这意味着他们可以使用相同的名称.但是,对象具有类,因此需要JVM上的错位名称.当前的Scala约定是在模块名称末尾添加$(对于顶级模块).如果对象是在类中定义的,我相信约定是OuterClass $ ModuleName $.要强制执行ScalaPower模块的单例属性,还有一个ModuleName $类的静态MODULE $成员.这是在类加载时初始化的,确保只有一个实例.这方面的一个副作用是,你应该不会做任何形式的模块构造锁定.

无论如何,Scala还内置了一个"为Java制作更好的"静态转发器机制.这是它在ScalaPower类上编写静态方法的地方,它只调用ScalaPower $ .MODULE $ .someMethod().如果还定义了伴随类,则可以生成的转发器是有限的,因为不允许在JVM上与静态和实例级方法发生命名冲突.我认为在2.8.0中这意味着如果你有一个伴侣对象,你将失去静态转发器.

在这种情况下,"最佳实践"是始终使用ScalaPower $ .MODULE $引用而不是静态转发器,因为转发器可能会随着ScalaPower类的修改而消失.

编辑:错字


Arj*_*ijl 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));       
    }
}
Run Code Online (Sandbox Code Playgroud)

运行如下:

java -cp .:<path-to/scala/install-dir>/lib/scala-library.jar test

给出了我的输出:

show my power: 0, 1, 2


Ry4*_*ase 9

我认为这间接涵盖了它:

伴随对象和Java静态方法

还有一件事需要了解伴侣对象.每当定义要用作应用程序入口点的main方法时,Scala都要求您将其放在对象中.但是,在撰写本文时,无法在伴随对象中定义主要方法.由于生成的代码中的实现细节,JVM将找不到main方法.此问题可能在将来的版本中得到解决.现在,您必须在单个对象中定义任何main方法(即"非伴侣"对象)[ScalaTips].请考虑以下一个简单的Person类和试图定义main的伴随对象的示例.

如在此处找到:http://programming-scala.labs.oreilly.com/ch06.html

简而言之,因为你的Object是一个伴侣对象(有一个伴侣类)你不能像你期望的那样调用它.正如你发现的那样,如果你摆脱了这个课程,它就能奏效.

  • 这不再是真的.介于编写和Scala 2.8发布之间的某个时间点,修复了转发代码生成模式,以允许同伴中的主要方法. (3认同)
  • 我们这里有一个断开的链接 (2认同)