如何在Java中实现Scala Apply方法

杰罗恩·克兰森(Jeroen Kransen)

我想从Scala代码中调用一些Java代码。我想使用Scala的apply结构,所以我可以这样称呼它:

val led = OutPin(0)

代替:

val led = new OutPin(0)

我天真地在Java代码中实现了一个附加的apply方法,如下所示:

public class OutPin {

    public OutPin(int pinNumber) {
    }

    public OutPin apply(int pinNumber) {
        return new OutPin(pinNumber);
    }
}

这不会编译我的Scala代码(上面的第一行),而是给了我一个错误:

对象OutPin不是值

用Java实现Scala的apply方法的正确方法是什么?

史蒂夫·沃尔德曼

您的问题不是本质上的apply方法,而是试图在Java中实现Scala单例对象。

我认为(但不确定)这在设计上是非常困难的,甚至是不可能的。

考虑一个非常非常简单的情况:

object Obj;

这将编译为两个JVM bytcode文件Obj$.classObj.class从理论上讲,只需检查这两个类的字节码,然后在Java中重新表达相同的内容,应该很容易。Scala单例对象的基本结构非常非常简单:

  1. 对于一个单对象Obj,一个Obj.classObj$.class必须产生
  2. Obj$类必须有一个public final static类型的字段Obj$称为MODULE$,这将在类初始化初始化指的是单独的对象。在Scala中,调用以Obj.foo()映射到Obj$.MODULE$.foo()[...如果Obj有一个名为的方法foo(),那就是!]
  3. Java编译器对这些Scala生成的类对一无所知,因此对于Java interop,Obj该类包含静态函数,这些静态函数只转发给具有相同名称和签名的方法的调用Obj$.MODULE$

这听起来很复杂,但实际上并没有那么多。编写到目前为止已经完成的一对Java类很简单。但是Scala编译器(2.10.3)仍然不会将这对构成Scala单例。深入研究Scala编译器生成的单例的字节码,您会发现有些细节很难用合法的Java表达。[提示:javap -c -p -s -v <fully-qualified-class-name>]

例如,最终的静态MODULE$字段由静态初始化程序间接初始化。静态初始化器只是构造一个Obj$对象,而无需直接分配它。分配发生在私有构造函数中。在Java中这是非法的:必须在静态初始值设定项中初始化空白的静态final,并且不能在可能从初始值设定项外部多次调用的代码(如私有构造函数)中进行分配。Scala编译器生成尊重空白最终语义的字节码(因为私有构造函数仅被调用一次),但超出了Java编译器验证那些语义的能力。因此,如果用Java表示,则该代码将被拒绝。

另外,Obj该类(不带终端美元符号的版本)包含类型为ScalaSig的注释,该注释看起来相当复杂,并且难以手动复制(在Java或Scala中),至少对于我们中的那些人不确定注释工程。

在决定将一对类视为“值”(这是一个有效的Scala单例对象)之前,我不确切知道Scala编译器会寻找什么,但是尽管Scala的简单性,但Scala的设计师选择不使其变得简单。基本方案。他们可能希望保留重组scala单例对象如何转换为字节码的能力。让Java程序员合成Scala单例对象将有效地使当前方案成为Scala公共API的永久组成部分。

注意,编写一个普通的非单例类,其实例具有apply(...)方法,因此可以像调用函数一样从Java轻松进行并且工作正常。这是一只Java猫:

public class Cat {
    public String apply( int i ) {
        return "Meow: " + i;
    }
}

这是Scala加糖应用的用法:

Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_45).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val Morris = new Cat;
Morris: Cat = Cat@6b4feafa

scala> Morris(8)
res0: String = Meow: 8

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Java中实现方法链接?

来自分类Dev

如何在Java中实现接口方法?

来自分类Dev

如何在Scala中实现多态方法的最小模拟?

来自分类Dev

如何在Java中实现抽象静态方法?

来自分类Dev

如何在Java中实现泛型方法

来自分类Dev

如何在Java中实现许多类通用的定制方法?

来自分类Dev

我们如何在Java中实现方法缓存

来自分类Dev

如何在单独的 Java 类的 OnClick() 方法中实现 startActivity()?

来自分类Dev

如何在 Java 中修复/实现 equals 方法?

来自分类Dev

如何在Java中为LinkedList实现实现append和deleteNode方法?

来自分类Dev

如何在 Scala 中公开 Kafka 的 Java 方法(commitSync with partitions)?

来自分类Dev

在Scala中继承Apply方法

来自分类Dev

在scala中调用超类apply方法

来自分类Dev

如何实现Java方法在Scala中返回使用数组参数化的泛型类型?

来自分类Dev

JavaScript的apply()方法如何工作?

来自分类Dev

如何调用JS .apply()方法

来自分类Dev

如何在SherlockFragment中实现onCreateOptionsMenu方法?

来自分类Dev

如何在SailsJS中实现beforeDestroy方法?

来自分类Dev

如何在特征中实现异步方法?

来自分类Dev

如何在SherlockFragment中实现onCreateOptionsMenu方法?

来自分类Dev

如何在signalR中实现“on”方法?

来自分类Dev

如何在实现文件中实现虚拟方法?

来自分类Dev

如何在Java中实现列表中的列表?还是有比列表列表更好的方法?

来自分类Dev

如何在Scala中使用多个可变参数方法实现Java接口(类型橡皮擦问题)?

来自分类Dev

如何在Java中实现Azure云服务的RoleEntryPoint.OnStop方法

来自分类Dev

如何在Java的try-catch块中强制方法的实现?

来自分类Dev

如何在Java数组中实现线性插值方法?

来自分类Dev

在Scala的Trait中使用Apply方法

来自分类Dev

如何在Scala中编写通用方法?

Related 相关文章

  1. 1

    如何在Java中实现方法链接?

  2. 2

    如何在Java中实现接口方法?

  3. 3

    如何在Scala中实现多态方法的最小模拟?

  4. 4

    如何在Java中实现抽象静态方法?

  5. 5

    如何在Java中实现泛型方法

  6. 6

    如何在Java中实现许多类通用的定制方法?

  7. 7

    我们如何在Java中实现方法缓存

  8. 8

    如何在单独的 Java 类的 OnClick() 方法中实现 startActivity()?

  9. 9

    如何在 Java 中修复/实现 equals 方法?

  10. 10

    如何在Java中为LinkedList实现实现append和deleteNode方法?

  11. 11

    如何在 Scala 中公开 Kafka 的 Java 方法(commitSync with partitions)?

  12. 12

    在Scala中继承Apply方法

  13. 13

    在scala中调用超类apply方法

  14. 14

    如何实现Java方法在Scala中返回使用数组参数化的泛型类型?

  15. 15

    JavaScript的apply()方法如何工作?

  16. 16

    如何调用JS .apply()方法

  17. 17

    如何在SherlockFragment中实现onCreateOptionsMenu方法?

  18. 18

    如何在SailsJS中实现beforeDestroy方法?

  19. 19

    如何在特征中实现异步方法?

  20. 20

    如何在SherlockFragment中实现onCreateOptionsMenu方法?

  21. 21

    如何在signalR中实现“on”方法?

  22. 22

    如何在实现文件中实现虚拟方法?

  23. 23

    如何在Java中实现列表中的列表?还是有比列表列表更好的方法?

  24. 24

    如何在Scala中使用多个可变参数方法实现Java接口(类型橡皮擦问题)?

  25. 25

    如何在Java中实现Azure云服务的RoleEntryPoint.OnStop方法

  26. 26

    如何在Java的try-catch块中强制方法的实现?

  27. 27

    如何在Java数组中实现线性插值方法?

  28. 28

    在Scala的Trait中使用Apply方法

  29. 29

    如何在Scala中编写通用方法?

热门标签

归档