ClassWriter cw = new ClassWriter(...);
byte[] bytes = cw.toByteArray();
Run Code Online (Sandbox Code Playgroud)
我想从bytes数组创建新的类实例.我该怎么做呢?有可能吗?
我想编写一个MethodVisitor来转换用于乘法的LDC指令.
字节码示例:
ldc #26
imul
Run Code Online (Sandbox Code Playgroud)
这基本上推动了一个常数然后乘以它.
它必须是有状态的转换,因为我首先必须检查它是否为乘法,如果是,我需要返回到ldc指令并修改常量.我不完全确定我会怎么做,我不知道如何修改常量(当我尝试传递一个不同的值时,旧的值仍然保留在常量池中).
编辑:
public class AdditionTransformer extends MethodAdapter {
boolean replace = false;
int operand = 0;
AdditionTransformer(MethodVisitor mv) {
super(mv);
}
@Override
public void visitInsn(int opcode) {
if (opcode == IMUL && replace) {
operand *= 2;
visitLdcInsn(operand);
replace = false;
}
mv.visitInsn(opcode);
}
@Override
public void visitLdcInsn(Object cst) {
if (cst instanceof Integer && !replace) {
operand = (Integer) cst;
replace = true;
} else {
mv.visitLdcInsn(cst);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我所拥有的,但它不会删除常量池中的旧值,并且可能存在错误.
假设我有一个抽象类:
abstract class Foo extends Bar {
public abstract int foo();
}
Run Code Online (Sandbox Code Playgroud)
我想在运行时扩展以创建一个Class对象.希望是我可以拥有一个动态生成的类:
class FooImpl extends Foo {
@Override
public int foo() {
return 5;
}
}
Run Code Online (Sandbox Code Playgroud)
这将由一个Class对象表示,然后我可以使用反射来创建新的实例.关键是我想在运行时决定方法foo()的返回值.我的想法是使用ASM为类创建字节码,然后在ClassLoader对象上使用反射来定义类.
使用ASM然后在生成的字节上反映方法ClassLoader #defineClass是在运行时使用非硬编码值实现抽象方法的最佳方法吗?
如果是的话,我将如何做到这一点.我的直觉是利用ASMifierClassVisitor,但我不确定这样做的确切方法.我知道如果所有其他方法都失败了,我可以手动完成定义特定类所需的JVM指令,但我觉得必须有一个更简单的方法.
如果不是,最好的方法是什么,我将如何使用最佳方式?
编辑:我检查了所有答案,我认为它们都不是我想要的.我最终创建了一个与ASM谈论的小实现.我想我应该在这里发布:
import org.objectweb.asm.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
/**
* Created by IntelliJ IDEA.
* User: Matt
* Date: 9/17/11
* Time: 12:42 PM
*/
public class OverrideClassAdapter extends ClassAdapter {
private final HashMap<String, Object> code;
private final String …Run Code Online (Sandbox Code Playgroud) 我有一个我已实现的自定义注释,我想使用注释处理器生成我的应用程序中使用该特定注释的所有类的列表.
我发现本教程描述了如何使用注释处理器生成类文件,因此使用我的注释为每个类生成一个类应该很容易.
我无法弄清楚的是我如何将所有这些信息收集到一个类中.似乎没有办法修改类,所以一旦第一次生成类,我就无法将新项添加到列表中.
有没有办法使用注释处理器生成一个方法,该方法将返回应用程序中使用特定注释注释的所有类的列表?
我是ASM的新手,我想要一些与字节码转换相关的帮助.
问题:我想通过ASM在字节码中为整个方法添加try/catch块,并希望使用java -noverify选项运行该方法.我可以为整个方法添加try/catch块,但是当我尝试执行该方法时,我得到'java.lang.VerifyError'.如果我使用java -noverify选项,那么它将运行.请帮我.
以下是详细信息.
public class Example {
public static void hello() {
System.out.println("Hello world");
}
}
Run Code Online (Sandbox Code Playgroud)
我想转换上面的代码,如下所示,使用ASM字节码检测引入try/catch块.
public class Example {
public static void hello() {
try
{
System.out.println("Hello world");
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
下面的代码添加了try/catch块,但无法使用java -noverify选项执行代码.
public class InstrumentExample {
/**
* Our custom method modifier method visitor class. It delegate all calls to
* the super class. Do our logic of adding try/catch block
*
*/
public static class ModifierMethodWriter extends MethodVisitor { …Run Code Online (Sandbox Code Playgroud) 我是ASM框架的新手.我已经在这个ASM框架上工作了一个星期.我在网上看过关于解析类和从头开始生成.class文件的教程.但我无法遵循如何修改ASM中的现有类.
请帮助我.
我无法遵循ClassVisitor,ClassWriter和ClassReader之间的执行流程.
请通过为我提供以下代码的ASM示例来解决我的问题.
public class ClassName {
public void showOne()
{
System.out.println("Show One Method");
}
public static void main(String[] args) {
ClassName c=new ClassName();
c.showOne();
}
}
Run Code Online (Sandbox Code Playgroud)
上述类应修改为:
public class ClassName {
public void showOne()
{
System.out.println("Show One Method");
}
public void showTwo()
{
System.out.println("Show Two Method");
}
public static void main(String[] args) {
ClassName c=new ClassName();
c.showOne();
c.showTwo();
}
}
Run Code Online (Sandbox Code Playgroud)
什么应该是ASM代码来修改它?
我使用ASMifier工具生成代码.但我不知道在哪里应用它.
请帮我.+
我正在使用ASM(字节码修改库),它以字节码命名格式提供对类型名称的访问,例如,报告String字段具有描述:Ljava/lang/String
我需要为某些类调用Class.forName,但是我需要类型名称的源代码形式,例如java.lang.String.
有没有办法从内部名称转换为Java源格式?
当访问方法指令a.doAnother(account.getId);使用visitMethodInsn()时ASM.我需要从方法参数获取帐户account.getId()类型,帐户类型是Account.但是我得到的返回类型account.getId()是long.如何获得Account此处的帐户类型?