Alp*_*ran 5 java decompiling scala
我做了一个非常简单的Scala程序,只打印Hello World:
object HelloWorldActivity {
def main(args: Array[String]) {
println("Hello, world")
}
}
Run Code Online (Sandbox Code Playgroud)
为了理解Scala如何转换为Java字节码,我反编译了生成的jar文件,其中有两个文件:HelloWorldActivity.class和HelloWorldActivity$.class.
第一个包含此代码:
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes="****************")
public final class HelloWorldActivity
{
public static void main(String[] paramArrayOfString)
{
HelloWorldActivity..MODULE$.main(paramArrayOfString);
}
}
Run Code Online (Sandbox Code Playgroud)
而第二个包含:
import scala.Predef.;
public final class HelloWorldActivity$
{
public static final MODULE$;
static
{
new ();
}
public void main(String[] args)
{
Predef..MODULE$.println("Hello, world");
}
private HelloWorldActivity$()
{
MODULE$ = this;
}
}
Run Code Online (Sandbox Code Playgroud)
我无法理解的是以下内容:
static
{
new ();
}
Run Code Online (Sandbox Code Playgroud)
将new ()内部空置的原因是什么static,以及如何static单独抛出编译/运行错误?
如果它有助于我使用http://gradle.org/docs/current/userguide/scala_plugin.html
有这个build.gradle:
apply plugin: 'scala'
repositories{
mavenCentral()
mavenLocal()
}
dependencies{
compile "org.scala-lang:scala-library:2.10.1"
}
Run Code Online (Sandbox Code Playgroud)
反编译器没有在那里生成有效的Java代码.
这是javap -p -v 'HelloWorldActivity$'显示:
public static {};
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: new #2 // class HelloWorldActivity$
3: invokespecial #12 // Method "<init>":()V
6: return
Run Code Online (Sandbox Code Playgroud)
那只是创建一个新的类实例.因此,反编译器应该已经为静态初始化器显示了此代码:
static {
new HelloWorldActivity$();
}
Run Code Online (Sandbox Code Playgroud)
首次加载类时,静态初始化程序执行一次.这通常会在HelloWorldActivity首次执行main方法时发生,因为这是使用的代码所在的HelloWorldActivity$位置.
请注意,静态初始化程序不会将引用存储到新创建的实例中.相反,构造函数将引用this(即对单例实例的引用)存储到MODULE$字段中.
private HelloWorldActivity$();
descriptor: ()V
flags: ACC_PRIVATE
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #29 // Method java/lang/Object."<init>":()V
4: aload_0
5: putstatic #31 // Field MODULE$:LHelloWorldActivity$;
8: return
Run Code Online (Sandbox Code Playgroud)
或者,正如您的反编译器正确显示:
private HelloWorldActivity$() {
MODULE$ = this;
}
Run Code Online (Sandbox Code Playgroud)
编辑:关于static {…}定义静态初始化程序的语法,请参阅Java语言规范§8.7静态初始化程序以获取参考.通过{…}在类中编写块,也可以编写实例初始化器.在创建类的每个实例时执行实例初始化器,其方式与执行字段初始化的方式非常相似.