2017-03-08 12 views
1

私はASM ClassVisitorを拡張し、訪問したクラスが匿名クラスであるかどうかを知りたがっています。ASMの匿名クラスにアクセスしているかどうかはどのように確認できますか?

私はクラスファイルを持っているので、クラスファイル名が$ [1-9] [0-9] *。classで終わると、匿名クラスになります。しかし、通貨文字はクラス名で有効です。たとえば、匿名クラスではないにもかかわらず、MyClass $ 1という名前のクラスが一致します(クラスファイルの名前はMyClass $ 1.class)。私はほとんどの人がこのようなことをおそらく名付けないだろうが、それは許されていることを知っている。

visitOuterClassメソッドをオーバーライドして、$#で終わる名前の外部クラスを削除する外部クラスがあるかどうかを確認しましたが、$ 1などで終わる内部の非匿名クラス名を持つこともできます。

匿名のクラスを訪問していることをASMに知らせる方法はありますか?または私よりも良いトリックですか?

#は、任意の数を意味する(正規表現[1-9] [0-9] *)

答えて

2

関連基準がクラスInnerClasses attributeは匿名の内部クラスであるクラスを宣言するかどうかです。 ASMは、属性の各エントリについて、visitInnerClassを呼び出して内容を報告します(存在する場合)。

だから、

java/lang/Object: is not an inner class 
java/util/Map$Entry: is a named inner class 
CheckForInnerClass$1: is an anonymous inner class 
+0

ありがとうを印刷し

public class CheckForInnerClass extends ClassVisitor { public static void main(String[] args) throws IOException { Class<?>[] test={ Object.class, Map.Entry.class, new Object(){}.getClass() }; for(Class<?> c: test) { new ClassReader(c.getName()) .accept(new CheckForInnerClass(Opcodes.ASM5), ClassReader.SKIP_CODE); } } private String actualName; private Boolean anonymous; public CheckForInnerClass(int api) { super(Opcodes.ASM5); } @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { actualName=name; } @Override public void visitInnerClass(String name, String outer, String innerName, int access) { if(name.equals(actualName)) { anonymous = innerName==null; } } @Override public void visitEnd() { System.out.println(actualName+": is " + (anonymous==null? "not an": anonymous? "an anonymous": "a named") + " inner class"); } } 

のようにそれを確認することができます!これについて数日のうちに考えている/グーグルグーグルでいる。 – osundblad

関連する問題