Javaのクラス内に存在する定数値をメソッド毎に出力する
Javaのクラス内が依存しているフィールド、メソッドの一覧を表示する - A.R.N [日記] の続き。
Javaの各クラス内で書かれたSQL文を抽出したかったので、Javassist を使って定数を抜いてみた。
本当は、スタック位置をきちんと考えてメソッドの引数としてどの定数が設定されているかまで調べたかったけれど、スタックマシンを実装するに等しくなってしまうのでそこは断念。
ClassPool cp = ClassPool.getDefault(); CtClass cc = cp.get("test.Sample"); for (CtBehavior cb : cc.getDeclaredBehaviors()) { MethodInfo info = cb.getMethodInfo2(); ConstPool pool = info.getConstPool(); CodeAttribute code = info.getCodeAttribute(); if (code == null) return; CodeIterator i = code.iterator(); while (i.hasNext()) { int pos = i.next(); int opecode = i.byteAt(pos); switch (opecode) { case Opcode.LDC: case Opcode.LDC_W: case Opcode.LDC2_W: case Opcode.ACONST_NULL: case Opcode.ICONST_0: case Opcode.ICONST_1: case Opcode.ICONST_2: case Opcode.ICONST_3: case Opcode.ICONST_4: case Opcode.ICONST_5: case Opcode.FCONST_0: case Opcode.FCONST_1: case Opcode.FCONST_2: case Opcode.BIPUSH: case Opcode.SIPUSH: { Object value; if (opecode == Opcode.ACONST_NULL) { value = null; } else if (opecode == Opcode.LDC) { value = pool.getLdcValue(i.byteAt(pos + 1)); } else if (opecode == Opcode.LDC_W) { value = pool.getLdcValue(i.u16bitAt(pos + 1)); } else if (opecode == Opcode.LDC2_W) { value = pool.getLdcValue(i.u16bitAt(pos + 1)); } else if (opecode == Opcode.ICONST_0) { value = 0; } else if (opecode == Opcode.ICONST_1) { value = 1; } else if (opecode == Opcode.ICONST_2) { value = 2; } else if (opecode == Opcode.ICONST_3) { value = 3; } else if (opecode == Opcode.ICONST_4) { value = 4; } else if (opecode == Opcode.ICONST_5) { value = 5; } else if (opecode == Opcode.FCONST_0) { value = 0.0F; } else if (opecode == Opcode.FCONST_1) { value = 1.0F; } else if (opecode == Opcode.FCONST_2) { value = 2.0F; } else if (opecode == Opcode.DCONST_0) { value = 0.0; } else if (opecode == Opcode.DCONST_1) { value = 1.0; } else if (opecode == Opcode.BIPUSH) { value = i.byteAt(pos + 1); } else { value = i.s16bitAt(pos + 1); } System.out.print(cc.getName()); System.out.print('\t'); System.out.print(cb.getLongName()); System.out.print('\t'); System.out.print("stack"); System.out.print('\t'); if (value instanceof String) { System.out.print('"'); System.out.print(value); System.out.print('"'); } else { System.out.print(value); } System.out.println(); break; } } } }