我想从Scala代码中调用一些Java代码.我想使用Scala的apply构造,所以我可以像这样调用它:
val led = OutPin(0)
Run Code Online (Sandbox Code Playgroud)
代替:
val led = new OutPin(0)
Run Code Online (Sandbox Code Playgroud)
我天真地在我的Java代码中实现了一个额外的apply方法,如下所示:
public class OutPin {
public OutPin(int pinNumber) {
}
public OutPin apply(int pinNumber) {
return new OutPin(pinNumber);
}
}
Run Code Online (Sandbox Code Playgroud)
这不会使我的Scala代码(上面的第一行)编译,而是给我一个错误:
对象OutPin不是值
在Java中实现Scala的apply方法的正确方法是什么?
Ste*_*man 14
您的问题不是使用apply方法本身,而是尝试在Java中实现Scala单例对象.
我认为(但不确定)这是非常困难的,甚至是不可能的.
考虑一个非常非常简单的案例:
object Obj;
Run Code Online (Sandbox Code Playgroud)
这将编译为两个JVM bytcode文件,Obj$.class和Obj.class.从理论上讲,只检查这两个类的字节码应该很容易,并在Java中重新表达同样的东西.Scala单例对象的基本结构非常非常简单:
Obj,一个Obj.class和Obj$.class必须产生Obj$类必须有一个public final static类型的字段Obj$称为MODULE$,这将在类的初始化初始化指的是单独的对象.在Scala中,调用Obj.foo()被映射到Obj$.MODULE$.foo()[...如果Obj有一个方法被调用foo(),那就是!]Obj该类包含静态函数,这些函数只转发给具有相同名称和签名的方法的调用Obj$.MODULE$.这听起来很复杂,但实际上并非如此.编写一对迄今为止的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单例对象转换为字节码的能力.让Java程序员合成scala单例对象将有效地使当前方案成为Scala公共API的永久部分.
请注意,编写一个普通的非单例类,其实例具有apply(...)方法,因此可以像Java一样调用,并且工作正常.这是一只Java猫:
public class Cat {
public String apply( int i ) {
return "Meow: " + i;
}
}
Run Code Online (Sandbox Code Playgroud)
这是使用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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1503 次 |
| 最近记录: |