MyCLassLoader loader=new MyCLassLoader(); Class c=loader.defineClass(bs);
ITest ins=(ITest)c.newInstance(); ins.setTest(100.0d); System.out.println(ins.getTest()); } public interface ITest{ public double getTest(); public void setTest(double d); } public static class MyCLassLoader extends ClassLoader{ public Class defineClass(byte[] data){ return super.defineClass(null,data,0,data.length,null); } } }
cw.visit(0x31,Modifier.PUBLIC,"Example",null,"java/lang/Object",new String[]{"java/lang/Cloneable"});
我改成DLOAD报错,不改还是ILOAD也报错
Arguments can't fit into locals in class file报这个错,另外我是直接拿INT类型的代码复制过去的就把类型从I改为D
谢谢
String field = "test";
Object defaultValue = 123d;
String setMd = "set" + StringUtils.capitalize(field);
String getMd = "get" + StringUtils.capitalize(field);
cw.visitField(
ACC_PRIVATE,
field,
"D",
null,
defaultValue == null ? null : Double.parseDouble(defaultValue.toString())).visitEnd(); MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, getMd, "()D", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, className, field, "D");
mv.visitInsn(IRETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
cw.visitEnd(); mv = cw.visitMethod(ACC_PUBLIC, setMd, "(D)V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ILOAD, 1);
mv.visitFieldInsn(PUTFIELD, className, field, "D");
mv.visitInsn(RETURN);
mv.visitMaxs(2, 2);
// variables
mv.visitEnd();
这是我的代码生成时报错,默认值也不管用
mv.visitVarInsn(ILOAD, 1);
这两行不知道是啥意思,不知道字段为String int double 的时候这设置是否一样
mv.visitMaxs(1, 1); 和 mv.visitMaxs(2, 2); 要分别改成
mv.visitMaxs(2, 2); 和 mv.visitMaxs(3, 3);
Object defaultValue = 123d;
String setMd = "set" + StringUtils.capitalize(field);
String getMd = "get" + StringUtils.capitalize(field);
cw.visitField(
ACC_PRIVATE,
field,
"D",
null,
defaultValue == null ? null : Double.parseDouble(defaultValue
.toString())).visitEnd(); MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, getMd, "()D", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, className, field, "D");
mv.visitInsn(IRETURN);
mv.visitMaxs(2, 2);
mv.visitEnd();
cw.visitEnd(); mv = cw.visitMethod(ACC_PUBLIC, setMd, "(D)V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ILOAD, 1);
mv.visitFieldInsn(PUTFIELD, className, field, "D");
mv.visitInsn(RETURN);
mv.visitMaxs(3, 3);
// variables
mv.visitEnd();
我是这样的,运行报错
Exception in thread "main" java.lang.VerifyError: (class: cn/gql/entity/UserInfo, method: setTest0 signature: (D)V) Register 1 contains wrong type
可否把帖出代码看下,是不是我哪还错着呢
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;public class TestAsm implements Opcodes{
public static void main(String[] args) throws InstantiationException, IllegalAccessException{
ClassWriter cw=new ClassWriter(0);
String className="Example";
cw.visit(0x31,ACC_PUBLIC,className,null,"java/lang/Object",new String[]{"java/lang/Cloneable",ITest.class.getName().replace('.','/')}); String field="test";
Object defaultValue=123d;
String setMd="setTest";
String getMd="getTest";
cw.visitField(ACC_PRIVATE,field,"D",null,defaultValue == null?null:Double.parseDouble(defaultValue.toString())).visitEnd();
MethodVisitor mv=cw.visitMethod(ACC_PUBLIC,getMd,"()D",null,null);
mv.visitCode();
mv.visitVarInsn(ALOAD,0);
mv.visitFieldInsn(GETFIELD,className,field,"D");
mv.visitInsn(DRETURN);
mv.visitMaxs(2,2);
mv.visitEnd();
cw.visitEnd(); mv=cw.visitMethod(ACC_PUBLIC,setMd,"(D)V",null,null);
mv.visitCode();
mv.visitVarInsn(ALOAD,0);
mv.visitVarInsn(DLOAD,1);
mv.visitFieldInsn(PUTFIELD,className,field,"D");
mv.visitInsn(RETURN);
mv.visitMaxs(3,3);
mv.visitEnd();
//下面产生构造方法
mv=cw.visitMethod(ACC_PUBLIC,"<init>","()V",null,null);
mv.visitCode();
mv.visitVarInsn(ALOAD,0);
mv.visitMethodInsn(INVOKESPECIAL,"java/lang/Object","<init>","()V");
mv.visitInsn(RETURN);
mv.visitMaxs(1,1);
mv.visitEnd();
cw.visitEnd(); byte[] bs=cw.toByteArray();
//FileUtil.writeFile("d:/test/asm/Example.class",bs);
MyCLassLoader loader=new MyCLassLoader();
Class c=loader.defineClass(bs);
ITest ins=(ITest)c.newInstance();
ins.setTest(100.0d);
System.out.println(ins.getTest());
} public interface ITest{
public double getTest();
public void setTest(double d);
} public static class MyCLassLoader extends ClassLoader{
public Class defineClass(byte[] data){
return super.defineClass(null,data,0,data.length,null);
}
}
}
如果不执行 ins.setTest(100.0d);则打印出的是0.0 ,不知道是哪的事?
cw.visitField(ACC_PRIVATE,field,"D",null,defaultValue == null?null:Double.parseDouble(defaultValue.toString())).visitEnd();
这是给字段赋了默认值了,但是打印出来的还是0.0,不知道哪的事
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;public class TestAsm implements Opcodes{
public static void main(String[] args) throws Exception{
ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_MAXS);//这样设置才能自动计算
String className="Example";
cw.visit(V1_5,ACC_PUBLIC,className,null,"java/lang/Object",new String[]{"java/lang/Cloneable",ITest.class.getName().replace('.','/')}); String field="test";
Object defaultValue=123d;
String setMd="setTest";
String getMd="getTest";
cw.visitField(ACC_PRIVATE,field,"D",null,null).visitEnd(); MethodVisitor mv=cw.visitMethod(ACC_PUBLIC,getMd,"()D",null,null);
mv.visitCode();
mv.visitVarInsn(ALOAD,0);
mv.visitFieldInsn(GETFIELD,className,field,"D");
mv.visitInsn(DRETURN);
mv.visitMaxs(0,0);// 自动计算局部变量和栈大小
mv.visitEnd();
cw.visitEnd(); mv=cw.visitMethod(ACC_PUBLIC,setMd,"(D)V",null,null);
mv.visitCode();
mv.visitVarInsn(ALOAD,0);
mv.visitVarInsn(DLOAD,1);
mv.visitFieldInsn(PUTFIELD,className,field,"D");
mv.visitInsn(RETURN);
mv.visitMaxs(0,0);// 自动计算
mv.visitEnd(); // 下面产生构造方法
mv=cw.visitMethod(ACC_PUBLIC,"<init>","()V",null,null);
mv.visitCode();
mv.visitVarInsn(ALOAD,0);
mv.visitMethodInsn(INVOKESPECIAL,"java/lang/Object","<init>","()V");
if(defaultValue != null){
//在构造方法中赋默认值
mv.visitVarInsn(ALOAD,0);
mv.visitLdcInsn(Double.parseDouble(defaultValue.toString()));
mv.visitFieldInsn(PUTFIELD,className,field,"D");
}
mv.visitInsn(RETURN);
mv.visitMaxs(0,0);// 自动计算
mv.visitEnd(); cw.visitEnd(); byte[] bs=cw.toByteArray();
// FileUtil.writeFile("d:/test/asm/Example.class",bs); MyCLassLoader loader=new MyCLassLoader();
Class c=loader.defineClass(bs); c.getConstructor(new Class[0]);
ITest ins=(ITest)c.newInstance();
//ins.setTest(100.0d);
System.out.println(ins.getTest());
} public interface ITest{
public double getTest(); public void setTest(double d);
} public static class MyCLassLoader extends ClassLoader{
public Class defineClass(byte[] data){
return super.defineClass(null,data,0,data.length,null);
}
}
}