2017-03-08 47 views
1

我已經擴展了ASM ClassVisitor並想知道匿名類中的訪問類。如何知道我是否訪問ASM中的匿名課程?

因爲我確實有類文件,我認爲如果類文件名以$ [1-9] [0-9] *。類結尾,它將是一個匿名類。但貨幣字符在類名中是有效的,例如名爲MyClass $ 1的類將會匹配(classfile被命名爲MyClass $ 1.class),即使它不是匿名類。我知道大多數人可能不會這樣命名,但它是允許的。

因此,我想重寫visitOuterClass方法,看看它是否有一個外部類,它可以消除名稱以$#結尾的外部類,但仍然可以有一個以例如$ 1結尾的內部非匿名類名。

那麼在ASM中有什麼方法可以知道它正在訪問一個匿名類嗎?或者比我的更好的技巧?

#是指任何數目(正則表達式:[1-9] [0-9] *)

回答

2

的有關標準是類InnerClasses attribute是否爲類定義爲一個匿名內部類。 ASM通過爲屬性的每個條目調用visitInnerClass來報告內容,如果存在的話。

所以,你可以檢查它像

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"); 
    } 
} 

它打印

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

謝謝!一直在思考/搜索這個開關幾天。 – osundblad