Scalaで書いたコードを逆コンパイルしてみる
環境
逆コンパイルしてみたソース
以下のようなソースをコンパイルしました。
- classではなくオブジェクトである
- 関数を引数にとるタイプの関数を使っている。
- 省略記法を使っている。
具体的には、プログラミングScala(初版第1刷)のP16〜P17のコードです。
以下にコードを示します。
package IntoroducingScala object Upper { def main(args: Array[String]) = { args.map(_.toUpperCase()).foreach(printf("%s",_)) println("") } }
逆コンパイル結果
コンパイルすると4つのファイルが得られますので、全て逆コンパイルしてみました。
コンパイルして得られたファイルは以下の4つです。
- Upper.class
- Upper$.class
- Upper$$anonfun$main$1.class
- Upper$$anonfun$main$2.class
変換結果ですが、綺麗に逆コンパイルできないコードがあるようで、一部不思議なことになっています。
Upper$.classのstatic初期化ブロックは結構不思議。
そういった謎はありつつも、以下については「なるほどー」という感じ。
- Javaとの互換性をもちつつ、objectで宣言したものはsingletonにする方法。
- 関数を引数にとるタイプの関数の実装方法。
Upper.class
package IntoroducingScala; import scala.reflect.ScalaSignature; @ScalaSignature(bytes="\006\0015:Q!\001\002\t\006\025\tQ!\0269qKJT\021aA\001\022\023:$xN]8ek\016LgnZ*dC2\f7\001\001\t\003\r\035i\021A\001\004\t\021\t!\t\021!E\003\023\t)Q\013\0359feN\031qA\003\n\021\005-\001R\"\001\007\013\0055q\021\001\0027b]\036T\021aD\001\005U\0064\030-\003\002\022\031\t1qJ\0316fGR\004\"a\005\f\016\003QQ\021!F\001\006g\016\fG.Y\005\003/Q\0211bU2bY\006|%M[3di\")\021d\002C\0015\0051A(\0338jiz\"\022!\002\005\0069\035!\t!H\001\005[\006Lg\016\006\002\037CA\0211cH\005\003AQ\021A!\0268ji\")!e\007a\001G\005!\021M]4t!\r\031BEJ\005\003KQ\021Q!\021:sCf\004\"a\n\026\017\005MA\023BA\025\025\003\031\001&/\0323fM&\0211\006\f\002\007'R\024\030N\\4\013\005%\"\002") public final class Upper { public static final void main(String[] paramArrayOfString) { Upper..MODULE$.main(paramArrayOfString); } }
Upper$.class(出力結果について一部改行位置を変更しています)
package IntoroducingScala; import java.io.Serializable; import scala.Array.; import scala.Predef.; import scala.ScalaObject; import scala.collection.IndexedSeqOptimized; import scala.collection.TraversableLike; import scala.reflect.ClassManifest.; import scala.runtime.AbstractFunction1; public final class Upper$ implements ScalaObject { public static final MODULE$; static { new (); } public void main(String[] args) { Predef..MODULE$.refArrayOps((Object[])Predef..MODULE$.refArrayOps((Object[])args).map( new AbstractFunction1() { public static final long serialVersionUID = 0L; public final String apply(String paramString) { return paramString.toUpperCase(); } } , Array..MODULE$.canBuildFrom(ClassManifest..MODULE$.classType(String.class)))).foreach( new AbstractFunction1() { public static final long serialVersionUID = 0L; public final void apply(String paramString) { Predef..MODULE$.printf("%s", Predef..MODULE$.genericWrapArray(new Object[] { paramString })); } }); } private Upper$() { MODULE$ = this; } }
Upper$$anonfun$main$1.class
package IntoroducingScala; import java.io.Serializable; import scala.runtime.AbstractFunction1; public final class Upper$$anonfun$main$1 extends AbstractFunction1 implements Serializable { public static final long serialVersionUID; public final String apply(String) { } }
Upper$$anonfun$main$2.class
package IntoroducingScala; import java.io.Serializable; import scala.runtime.AbstractFunction1; public final class Upper$$anonfun$main$2 extends AbstractFunction1 implements Serializable { public static final long serialVersionUID; public final void apply(String) { } }