Java6にも対応したデコンパイラJavaDecompilerが超絶便利だった。
いままでJadを愛用していたのですがジェネリクスやEnumとかのときにデコンパイル失敗したりしていてなにかいいものが無いかと探していたらいいものを見つけました。
http://java.decompiler.free.fr/?q=jdgui#downloads
このツールお勧めな点が3つあって
という点。
Java5から導入されたジェネリクスやアノテーションに対応していること
たとえば以下のソースがコンパイルされたクラスファイルがあったとして
package jp.co.gara; import java.util.ArrayList; import java.util.List; public class EnumTest { enum OS {UNIX,MAX_OS,WINDOWS} public static void main(String[] args) { OS myOs = null; List<OS> list = new ArrayList<OS>(); list.add(OS.UNIX); list.add(OS.WINDOWS); list.add(OS.MAX_OS); list.add(OS.UNIX); for (OS os :list){ System.out.println("myos = " + os); } } }
jadの場合
こんな短いソースでもjadだとこんな感じ頑張ってしまうのですが
package jp.co.gara; import java.io.PrintStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class EnumTest { static final class OS extends java.lang.Enum { public static final jp.co.gara.OS UNIX; public static final jp.co.gara.OS MAX_OS; public static final jp.co.gara.OS WINDOWS; private static final jp.co.gara.OS ENUM$VALUES[]; public static jp.co.gara.OS[] values() { jp.co.gara.OS aos[]; int i; jp.co.gara.OS aos1[]; /* 1*/ java.lang.System.arraycopy(aos = VALUES, 0, aos1 = new jp.co.gara.OS[i = aos.length], 0, i); /* 1*/ return aos1; } public static jp.co.gara.OS valueOf(java.lang.String s) { /* 1*/ return (jp.co.gara.OS)java.lang.Enum.valueOf(jp/co/gara/EnumTest$OS, s); } static { /* 7*/ UNIX = new OS("UNIX", 0); /* 7*/ MAX_OS = new OS("MAX_OS", 1); /* 7*/ WINDOWS = new OS("WINDOWS", 2); /* 7*/ VALUES = (new jp.co.gara.OS[] { /* 7*/ UNIX, MAX_OS, WINDOWS }); } private OS(java.lang.String s, int i) { /* 7*/ super(s, i); } } public EnumTest() { } public static void main(java.lang.String args[]) { /* 9*/ jp.co.gara.OS myOs = null; /* 11*/ java.util.List list = new ArrayList(); /* 12*/ list.add(jp.co.gara.OS.UNIX); /* 13*/ list.add(jp.co.gara.OS.WINDOWS); /* 14*/ list.add(jp.co.gara.OS.MAX_OS); /* 15*/ list.add(jp.co.gara.OS.UNIX); jp.co.gara.OS os; /* 16*/ for (java.util.Iterator iterator = list.iterator(); iterator.hasNext(); java.lang.System.out.println((new StringBuilder("myos = ")).append(os).toString())) { /* 16*/ os = (jp.co.gara.OS)iterator.next(); } } }
JavaDecompilerの場合
JavaDecompilerなら以下のように綺麗。ForEachもEnumも綺麗に出してくれる。
JadのForEachが意味不明な状況になっているのと比べるとどれだけ見やすいかよくわかる。
package jp.co.gara; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; public class EnumTest { public static void main(String[] args) { OS myOs = null; List list = new ArrayList(); list.add(OS.UNIX); list.add(OS.WINDOWS); list.add(OS.MAX_OS); list.add(OS.UNIX); for (OS os : list) System.out.println("myos = " + os); } static enum OS { UNIX, MAX_OS, WINDOWS; } }
Jarファイルごとデコンパイルできる&折りたたんだりリンクで該当ソースに飛べる。
私としてはこれが一番便利。Jarの中身を見ることが多いのでJarファイルごと突っ込んでデコンパイルしてソースを読めるのは非常にありがたい。
いままではExplzhでJarの中身を参照しつつ対象クラスを右クリックからJad*1していたのと比べると格段に快適になりました。
さらに下線が引いてあるように他クラスへ飛ぶことが出来るのも最高。障害対応時にかなり活躍です。
インストール
GUI版はここ
http://java.decompiler.free.fr/?q=jdgui#downloads
Eclipseプラグイン版はここ
http://java.decompiler.free.fr/jd-eclipse/update
Eclipse版は試してませんが、私のように急にPJのソース読まなければならなかったり障害調査をする必要のない方はEclipse版でよいとおもいます。
参考
以下によるとノートン先生をいれているとVisual Studio 2008 Standard でReleaseが誤検知される問題にひっかかって誤検知されるらしいのできをつけてください。
Java DecompilerがNorton先生に怒られる話の続き。 - 谷本 心 in せろ部屋