2017-03-08 44 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