如何在Java中实现Scala apply方法
我想从
Scala代码调用一些
Java代码.我想使用Scala的应用程序,所以我可以这样称呼:
val led = OutPin(0) 代替: val led = new OutPin(0) 我在我的Java代码中天真地实现了一个附加的应用方法,如下所示: public class OutPin { public OutPin(int pinNumber) { } public OutPin apply(int pinNumber) { return new OutPin(pinNumber); } } 这不会使我的Scala代码(上面的第一行)编译,而是给我一个错误: Object OutPin不是一个值 在Java中实现Scala应用方法的正确方法是什么? 解决方法
你的问题不在于应用方法本身,而是试图在Java中实现一个Scala单例对象.
我认为(但不确定)这是非常困难的,甚至是不可能的设计. 考虑一个非常非常简单的情况: object Obj; 这编译为两个JVM字节码文件Obj $.class和Obj.class.在理论上,应该很容易检查这两个类的字节码,并在Java中重写相同的东西. Scala单身对象的基本结构非常简单: >对于一个单例对象Obj,必须生成一个Obj.class和Obj $.class 这听起来很复杂,但实际上并不是那么多.编写一对Java类很简单.但Scala编译器(2.10.3)仍然不会将该对识别为构成Scala单例.潜入到Scala编译器生成的单例的字节码,您将看到有一些在法律Java中难以表达的细节. [提示:javap -c -p -s -v< fully-qualified-class-name>] 例如,最终的静态MODULE $字段由静态初始化程序间接初始化.静态初始化器只是构造一个Obj $对象,而不需要直接赋值.分配发生在私有构造函数内.这在Java中是非法的:空白静态决赛必须在静态初始化程序中进行初始化,并且不能在可能从初始化程序外部多次调用的代码(如私有构造函数)中分配. Scala编译器生成符合空白最终语义的字节码(因为私有构造函数只调用一次),但超出了Java编译器验证这些语义的能力.所以如果用Java表达,这个代码将被拒绝. 此外,Obj类(没有终端美元符号的版本)包含一个类型为ScalaSig的注释,它看起来很复杂,手工难以重现(在Java或Scala中),至少对于我们这些此注释工作. 在决定将一对类视为“价值”之前,我不知道Scala编译器正在寻找什么,这是一个有效的Scala单例对象,但Scala的设计人员选择不使其变得容易,尽管简单基本方案他们可能希望保留重组scala singleton对象如何转换为字节码的能力.让Java程序员合成scala单例对象将有效地使当前的方案成为Scala公共API的永久部分. 注意,编写一个普通的非单例类,其实例具有apply(…)方法等等,可以像Java一样简单的调用函数,并且工作正常.这是一个Java猫: public class Cat { public String apply( int i ) { return "Meow: " + i; } } 以下是Scala’s sugared的用法: 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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |