이전에 ASM을 자세히 소개했습니다. 필요한 친구는 여기를 클릭하세요. Java 바이트코드 프레임워크 ASM 심층 연구
JVM 유형 서명 비교표
예를 들어, Java 메소드는
long f (int n, String s, int[] arr);
이고 해당 유형 서명은
f (ILjava/lang/String;[I)J
입니다. java 메소드는
private void hi(double a, List<String> b);
이고 해당 타입 시그니처는
hi (DLjava/util/List;)V
입니다. 다음으로 ASM을 사용하여 위의 두 가지 타입이 맞는지 확인할 수 있습니다. 서명이 정확함:
public class Test { public static void main(String[] args) throws Exception { ClassPrinter printer = new ClassPrinter(); //读取静态内部类Bazhang ClassReader cr = new ClassReader("Test$Bazhang"); cr.accept(printer, 0); } //静态内部类 static class Bazhang { public Bazhang(int a) { } private long f (int n, String s, int[] arr){ return 0; } private void hi(double a, List<String> b){ } } static class ClassPrinter extends ClassVisitor { public ClassPrinter() { super(Opcodes.ASM5); } @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { super.visit(version, access, name, signature, superName, interfaces); //打印出父类name和本类name System.out.println(superName + " " + name); } @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { //打印出方法名和类型签名 System.out.println(name + " " + desc); return super.visitMethod(access, name, desc, signature, exceptions); } } }
마지막으로 인쇄된 내용:
java/lang/Object Test$Bazhang <init> ()V f (ILjava/lang/String;[I)J hi (DLjava/util/List;)V
이전 정확성을 확인했습니다. 기본값 생성자도 인쇄됩니다.
그럼 다음에는 Bazhang 클래스에 새로운 메서드를 추가해 보겠습니다.
public void newFunc(String str){ }
이때 ClassWriter를 사용해야 합니다. ClassReader, ClassVisitor 및 ClassWriter에 대한 특정 기사를 보려면 다음 기사를 참조하세요. ASM 소스 코드 학습을 위한 ClassReader, ClassVisitor 및 ClassWriter에 대한 자세한 설명
public static void main(String[] args) throws Exception { ClassReader cr = new ClassReader(Bazhang.class.getName()); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); cr.accept(cw, Opcodes.ASM5); MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "newFunc", "(Ljava/lang/String;)V", null, null); mv.visitInsn(Opcodes.RETURN); mv.visitEnd(); // 获取生成的class文件对应的二进制流 byte[] code = cw.toByteArray(); //将二进制流写到out/下 FileOutputStream fos = new FileOutputStream("out/Bazhang222.class"); fos.write(code); fos.close(); }
out/폴더에 Bazhang222.class가 생성됩니다:
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // import java.util.List; class Test$Bazhang { Test$Bazhang() { } private long f(int n, String s, int[] arr) { return 0L; } private void hi(double a, List<String> b) { } public void newFunc(String var1) { } }
이전에 구성한 JVM 명령어 세트와 결합하여 ASM을 사용하여 직접 작동합니다. the bytecode 문제없습니다. 마지막에 ASM 소스코드 다운로드 주소가 첨부되어 있습니다: http://forge.ow2.org/projects/asm/
요약
위는 이 글의 내용이 모든 분들의 공부나 업무에 조금이나마 도움이 되었으면 좋겠습니다. 궁금한 점이 있으시면 메시지를 남겨주세요.
Java 바이트코드 프레임워크 ASM의 바이트코드 작동 방법에 대한 더 많은 관련 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!