[ASM教程]#6樹API

首發於Enaium的個人博客


使用樹API來生成一個類

public static void main(String[] args) {
    ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    ClassNode classNode = new ClassNode();
    classNode.visit(V1_8, ACC_PUBLIC, "cn/enaium/learn/asm/learn6/Learn6Test", null, "java/lang/Object", null);
    MethodNode methodNode = new MethodNode(ACC_PUBLIC + ACC_STATIC, "render", "()V", null, null);//一個方法
    methodNode.instructions.add(new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
    methodNode.instructions.add(new LdcInsnNode("Hello ASM!"));
    methodNode.instructions.add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false));
    methodNode.visitMaxs(2, 1);
    methodNode.instructions.add(new InsnNode(RETURN));
    classNode.methods.add(methodNode);//添加方法
    classNode.accept(classWriter);
    String name = Learn2.class.getResource("/cn/enaium/learn/asm/learn6/").getPath() + "Learn6Test.class";

    try {
        FileOutputStream out = new FileOutputStream(name);
        out.write(classWriter.toByteArray());
        out.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

字段或方法都在fieldsmethods裏是一個列表,並且操作也是一個列表(雙向鏈表),所以可以很容易的操作一個類。

接着再分析類。

try {
    ClassReader classReader = new ClassReader(new FileInputStream(name));
    ClassNode readClassNode = new ClassNode();
    classReader.accept(readClassNode,0);
    System.out.println(readClassNode.name);//類名
    for (MethodNode method : readClassNode.methods) {
        System.out.println(method.name);//方法名
        ListIterator<AbstractInsnNode> iterator = method.instructions.iterator();
        while (iterator.hasNext()) {
            AbstractInsnNode next = iterator.next();
            System.out.println(next.getClass());//操作
        }
    }
} catch (IOException e) {
    e.printStackTrace();
}

也可以把方法的操作給遍歷出來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章