我怎么知道我是否正在ASM访问匿名课程?

时间:2017-03-08 16:14:03

标签: anonymous-class java-bytecode-asm

我已经扩展了ASM ClassVisitor并想知道匿名类中是否访问过的类。

因为我有类文件,所以我认为如果类文件名以$ [1-9] [0-9] * .class结尾,那么它将是一个匿名类。但货币字符在类名中是有效的,例如,名为MyClass $ 1的类将匹配(类文件名为MyClass $ 1.class),即使它不是匿名类。我知道大多数人可能不会这样命名,但是这是允许的。

所以我考虑重写visitOuterClass方法以查看它是否有一个外部类可以消除名称以$#结尾的外部类,但是你仍然可以有一个内部非匿名类名,例如$ 1。 / p>

那么在ASM中有一些方法可以知道它正在访问一个匿名类吗?还是比我更好的技巧?

#表示任何数字(正则表达式:[1-9] [0-9] *)

1 个答案:

答案 0 :(得分: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