Birleştirme
- Java kursu
- Uzman
- Ders 41/46
- 6 dk
Tüm parçaları birleştirerek bir bytecode denetleyici yazarsın.
Proje: birleştirme
Son derste tüm parçaları birleştirip visitor zincirini tamamlayacaksın. ClassVisitor'a void visitEnd(); metodu eklenir; gezinin sonunda çağrılır. ClassReader.accept tüm metotlar gezildikten sonra v.visitEnd() çağırır.
ClassWriter.visitEnd bir kapanış satırı ekler; RenameVisitor.visitEnd bunu delegate'e iletir. Böylece tam bir boru hattı kurulur: ClassReader, RenameVisitor, ClassWriter.
tam boru hattı
Tam boru hattı şöyle çalışır: ClassReader sınıfı ve metotları gezer; her olayı önce RenameVisitor alır, dönüşüm uygular ve ClassWriter'a iletir; ClassWriter metni biriktirir. Gezi sonunda visitEnd kapanış satırını ekler.
Bu model, ASM'nin java ajanlarındaki çalışmasını yansıtır. Gerçek ASM'de ClassReader bayt kodunu ayrıştırır; burada ise ad ve metot listesiyle aynı akışı kurduk.
Uygulama visitEnd ekleyip zinciri tamamla
ClassVisitor arabirimine void visitEnd(); metodunu ekle. ClassReader.accept tüm metotlar gezildikten sonra v.visitEnd(); çağırsın. ClassWriter'a public void visitEnd() { sb.append("End").append("\n"); } ekle. RenameVisitor'a public void visitEnd() { delegate.visitEnd(); } ekle. main aynı kalsın: reader.accept(new RenameVisitor(writer)); ve System.out.println(writer.toString());.
Başlangıç kodu
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());
}
}Örnek çözüm
interface ClassVisitor {
void visitClass(String name);
void visitMethod(String name);
void visitEnd();
}
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);
v.visitEnd();
}
}
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 void visitEnd() { sb.append("End").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 void visitEnd() { delegate.visitEnd(); }
}
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 End
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Birleştirme adımında ne eklenir?
- Yeni thread
- visitEnd ile kapanış Doğru cevap
- Veri tabanı
- Grafik penceresi
Açıklama: visitEnd gezi sonunda kapanış çağrısı yapar.
2 visitEnd bildirisini tamamla
void ____();
void visitEnd();
Açıklama: void visitEnd(); gezi sonunu işaretler.
3 proje parçalarını özetle
| Kavram | Anlamı |
|---|---|
ClassReader |
Sınıfı gezer |
RenameVisitor |
Adı değiştirir |
ClassWriter |
Metin üretir |
visitEnd |
Geziyi kapatır |