via Matz にっき
Java のクラスファイルを作るようなので作られたクラスファイルを覗いてみよう.
Examples にある HelloWorld.scala を scalac でコンパイル.
すると HelloWorld.class と HelloWorld$.class ができた.
HelloWorld の方を javap -c してみる.
ちなみに,クラスパスに $SCALA_HOME/lib/scala.jar を加える必要がある.
Compiled from HelloWorld.scala
public final class HelloWorld extends java.lang.Object {
public static long executionStart();
public static void main(java.lang.String[]);
public static int $tag$0();
public static void $init$$0();
public static int $tag();
}
Method long executionStart()
0 getstatic #11 <Field HelloWorld$ MODULE$>
3 invokevirtual #13 <Method long executionStart()>
6 lreturn
Method void main(java.lang.String[])
0 getstatic #11 <Field HelloWorld$ MODULE$>
3 aload 0
5 invokevirtual #17 <Method void main(java.lang.String[])>
8 return
Method int $tag$0()
0 getstatic #11 <Field HelloWorld$ MODULE$>
3 invokevirtual #21 <Method int $tag$0()>
6 ireturn
Method void $init$$0()
0 getstatic #11 <Field HelloWorld$ MODULE$>
3 invokevirtual #25 <Method void $init$$0()>
6 return
Method int $tag()
0 getstatic #11 <Field HelloWorld$ MODULE$>
3 invokevirtual #28 <Method int $tag()>
6 ireturn
HelloWorld$.class の方も同じように javap してみると.
Compiled from HelloWorld.scala
public final class HelloWorld$ extends java.lang.Object implements scala.ScalaObject, scala.Application {
public static final HelloWorld$ MODULE$;
public static {};
public long executionStart();
public void main(java.lang.String[]);
public int $tag$0();
public void $init$$0();
public int $tag();
public HelloWorld$();
}
Method static {}
0 new #11 <Class HelloWorld$>
3 invokespecial #14 <Method HelloWorld$()>
6 return
Method long executionStart()
0 aload_0
1 getfield #19 <Field long executionStart$>
4 lreturn
Method void main(java.lang.String[])
0 ldc #23 <String "scala.time">
2 invokestatic #29 <Method java.lang.String getProperty(java.lang.String)>
5 aconst_null
6 astore 2
8 dup
9 ifnonnull 21
12 pop
13 aload 2
15 ifnull 74
18 goto 29
21 aload 2
23 invokevirtual #35 <Method boolean equals(java.lang.Object)>
26 ifne 74
29 getstatic #39 <Field java.io.PrintStream out>
32 new #41 <Class java.lang.StringBuffer>
35 dup
36 invokespecial #42 <Method java.lang.StringBuffer()>
39 ldc #44 <String "[total ">
41 invokevirtual #48 <Method java.lang.StringBuffer append(java.lang.Object)>
44 invokestatic #51 <Method long currentTimeMillis()>
47 aload_0
48 invokeinterface (args 1) #55 <InterfaceMethod long executionStart()>
53 lsub
54 invokestatic #61 <Method scala.Long box_lvalue(long)>
57 invokevirtual #48 <Method java.lang.StringBuffer append(java.lang.Object)>
60 ldc #63 <String "ms]">
62 invokevirtual #48 <Method java.lang.StringBuffer append(java.lang.Object)>
65 invokevirtual #67 <Method java.lang.String toString()>
68 invokevirtual #73 <Method void println(java.lang.String)>
71 goto 74
74 return
Method int $tag$0()
0 iconst_0
1 ireturn
Method void $init$$0()
0 aload_0
1 invokestatic #51 <Method long currentTimeMillis()>
4 putfield #19 <Field long executionStart$>
7 return
Method int $tag()
0 iconst_0
1 ireturn
Method HelloWorld$()
0 aload_0
1 invokespecial #78 <Method java.lang.Object()>
4 aload_0
5 putstatic #80 <Field HelloWorld$ MODULE$>
8 aload_0
9 invokevirtual #82 <Method void $init$$0()>
12 getstatic #87 <Field scala.Console$ MODULE$>
15 ldc #89 <String "Hello, world!">
17 invokevirtual #92 <Method void println(java.lang.Object)>
20 return
なるほど.scala.time がプロパティにセットされていると実行時間が出力されるのか.
へぇ.
流れとしては
HelloWorld#main → HelloWorld$#<clinit> → HelloWorld$#<init> → HelloWorld$#main
という流れか.
"Hello, world!" と出力されるのは HelloWorld$#<init>,ようするに
HelloWorld$ のコンストラクタで.
そのほかの $tag やら $init$$0 やら executionStart なんかはよくわからん.
多分 scala での定義済み関数かなんかなんだろう.
scala のドキュメント読んでないからよくわからん.