Groovy带有一个名为groovyc
的编译器。对于每个脚本,groovyc
生成一个扩展groovy.lang.Script
的类,其中包含一个main方法,以便Java可以执行它。已编译类的名称与正在编译的脚本的名称相匹配。
例如,使用此HelloWorld.groovy
脚本:
println "Hello World"
这就像这段代码:
class HelloWorld extends Script {
public static void main(String[] args) {
println "Hello World"
}
}
Scala附带了一个名为scalac
的编译器。
例如,使用相同的HelloWorld.scala
脚本:
println("Hello World")
代码对scalac
无效,因为编译器需要类或对象定义,但在Scala REPL Interpreter中有效。怎么可能?在执行之前它是否包含在类中?
答案 0 :(得分:5)
Scala-Script中的代码首先放在Scala对象中,然后编译为JVM-Bytecode,最后执行。您可以通过编写scala -Xprint:parser my_file.scala
:
package <empty> {
object Main extends scala.ScalaObject {
def <init>() = {
super.<init>();
()
};
def main(argv: Array[String]): scala.Unit = {
val args = argv;
{
final class $anon extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
println("hello world")
};
new $anon()
}
}
}
}
答案 1 :(得分:2)
scalac会将您的代码编译为java字节码。 println("Hello World")
本身不是有效的scala程序,因此scalac不会编译它。
你可以这样做:
object Test extends App {
println("Hello World")
}
或
object Test {
def main(args: Array[String]) {
println("Hello World")
}
}
然后,您可以使用scala Test
运行输出。
在仅包含println("Hello World")
行的文件上运行scala“解释器”将基本上将其包装在一个对象中(将其转换为我们上面看到的第一个表单),编译它并在引擎盖下为它运行它
请注意(即使代码看起来与java中的Hello World控制台应用程序非常相似),生成的编译程序不与编译此java的结果相同
/* note: this is Java code */
/* this does NOT compile to the same bytecode as the previous scala example*/
public class Test {
public static void main (String args[]) {
System.out.println ("Hello World");
}
}
答案 2 :(得分:1)
使用scalac
成功编译文件后,可以使用java类文件反汇编程序javap
查看生成的类和方法签名(编辑:感谢@Luigi指出它是生成签名,而不是代码)。也就是说,scalac HelloWorld.scala
后跟javap HelloWorld
。