CodeBlanks Logo Icon CodeBlanks

Bytecode dönüştürme

ASM ile bytecode dönüştürme yazarsın.

dönüştürücü visitor

Bir visitor, başka bir visitor'ı sarıp olayları değiştirebilir. Bu sarmalayıcı (decorator) deseni, ASM ajanlarının temelidir. RenameVisitor, içteki delegate visitor'a olayları iletirken metot adlarını değiştirebilir.

Örneğin visitMethod'ta n.replace("main", "start") yapıp delegate'e iletirsen, çıktıda main yerine start görünür. Dönüşüm şeffaftır: delegate yine aynıvisitor mantığını çalıştırır.

delegate sarmalama

RenameVisitor bir ClassVisitor delegate'ini kurucuda alır ve saklar. Her olayda önce dönüşümü uygular, sonra delegate'e iletir. visitClass'ta adı değiştirmeden geçirirken, visitMethod'ta yeniden adlandırma yapabilir.

Bu desen, ASM'de bayt kodu dönüştüren ajanlarda kullanılır: bir visitor zinciri kurulur, her halka bir işlem ekler. Son halka genelde ClassWriter'dır.

Uygulama RenameVisitor sınıfını yaz

Üstteki yapıya class RenameVisitor implements ClassVisitor ekle; ClassVisitor delegate alanı ve RenameVisitor(ClassVisitor delegate) yapıcısı olsun. visitClass(String n) metodu delegate.visitClass(n);, visitMethod(String n) metodu delegate.visitMethod(n.replace("main", "start")); çağırsın. main içinde ClassWriter writer = new ClassWriter(); oluştur, reader.accept(new RenameVisitor(writer)); çağır ve System.out.println(writer.toString()); ile yazdır.

Başlangıç kodu

Main.java
interface ClassVisitor {
    void visitClass(String name);
    void visitMethod(String name);
}

class ClassReader {
    String name;
    String[] methods;
    ClassReader(String name, String[] methods) {
        this.name = name;
        this.methods = methods;
    }
    void accept(ClassVisitor v) {
        v.visitClass(name);
        for (String m : methods) v.visitMethod(m);
    }
}

class ClassWriter implements ClassVisitor {
    StringBuilder sb = new StringBuilder();
    public void visitClass(String n) { sb.append("Class: ").append(n).append("\n"); }
    public void visitMethod(String n) { sb.append("Method: ").append(n).append("\n"); }
    public String toString() { return sb.toString().trim(); }
}

public class Main {
    public static void main(String[] args) {
        ClassReader reader = new ClassReader("Main", new String[]{"main"});
        ClassWriter writer = new ClassWriter();
        reader.accept(writer);
        System.out.println(writer.toString());
    }
}

Örnek çözüm

Main.java
interface ClassVisitor {
    void visitClass(String name);
    void visitMethod(String name);
}

class ClassReader {
    String name;
    String[] methods;
    ClassReader(String name, String[] methods) {
        this.name = name;
        this.methods = methods;
    }
    void accept(ClassVisitor v) {
        v.visitClass(name);
        for (String m : methods) v.visitMethod(m);
    }
}

class ClassWriter implements ClassVisitor {
    StringBuilder sb = new StringBuilder();
    public void visitClass(String n) { sb.append("Class: ").append(n).append("\n"); }
    public void visitMethod(String n) { sb.append("Method: ").append(n).append("\n"); }
    public String toString() { return sb.toString().trim(); }
}

class RenameVisitor implements ClassVisitor {
    ClassVisitor delegate;
    RenameVisitor(ClassVisitor delegate) {
        this.delegate = delegate;
    }
    public void visitClass(String n) { delegate.visitClass(n); }
    public void visitMethod(String n) { delegate.visitMethod(n.replace("main", "start")); }
}

public class Main {
    public static void main(String[] args) {
        ClassReader reader = new ClassReader("Main", new String[]{"main"});
        ClassWriter writer = new ClassWriter();
        reader.accept(new RenameVisitor(writer));
        System.out.println(writer.toString());
    }
}

Beklenen çıktı

Class: Main
Method: start

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 yeniden adlandırma çağrısını tamamla

Soru
return name.____("main", "start");
Cevap
return name.replace("main", "start");

Açıklama: name.replace("main", "start") metodu yeniden adlandırır.

2 Dönüştürücü visitor ne yapar?

  • Olayları değiştirerek iletir Doğru cevap
  • Bayt kodu derler
  • Thread başlatır
  • Sınıfı siler

Açıklama: Dönüştürücü visitor olayları değiştirip delegate'e iletir.

3 dönüşüm öğelerini eşleştir

Kavram Anlamı
delegate Sarmalanan visitor
replace Yeniden adlandırma
visitMethod Metot olayı
RenameVisitor Dönüştürücü sınıf

Uzman bölümündeki tüm dersler