Java
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.
Örnek çözümü göster
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());
}
}
Kendini test et
-
yeniden adlandırma çağrısını tamamla
return name.____("main", "start");
Cevabı göster
return name.replace("main", "start");
-
Dönüştürücü visitor ne yapar?
- Olayları değiştirerek iletir
- Bayt kodu derler
- Thread başlatır
- Sınıfı siler
Cevabı göster
Olayları değiştirerek iletir — Dönüştürücü visitor olayları değiştirip delegate'e iletir.
-
dönüşüm öğelerini eşleştir
- delegate
- Sarmalanan visitor
- replace
- Yeniden adlandırma
- visitMethod
- Metot olayı
- RenameVisitor
- Dönüştürücü sınıf
Sıradaki ders: Birleştirme