>Java >java지도 시간 >Java 바이트코드 프레임워크 ASM에서 바이트코드를 작동하는 방법에 대한 간략한 분석

Java 바이트코드 프레임워크 ASM에서 바이트코드를 작동하는 방법에 대한 간략한 분석

高洛峰
高洛峰원래의
2017-01-23 10:23:511768검색

이전에 ASM을 자세히 소개했습니다. 필요한 친구는 여기를 클릭하세요. Java 바이트코드 프레임워크 ASM 심층 연구

JVM 유형 서명 비교표

Java 바이트코드 프레임워크 ASM에서 바이트코드를 작동하는 방법에 대한 간략한 분석

예를 들어, 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 중국어 웹사이트를 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.