diff --git a/src/main/java/org/redkale/asm/Asms.java b/src/main/java/org/redkale/asm/Asms.java new file mode 100644 index 000000000..f1cc00e82 --- /dev/null +++ b/src/main/java/org/redkale/asm/Asms.java @@ -0,0 +1,163 @@ +/* + * + */ +package org.redkale.asm; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import static org.redkale.asm.Opcodes.BIPUSH; +import static org.redkale.asm.Opcodes.CHECKCAST; +import static org.redkale.asm.Opcodes.GETSTATIC; +import static org.redkale.asm.Opcodes.ICONST_0; +import static org.redkale.asm.Opcodes.INVOKESTATIC; +import static org.redkale.asm.Opcodes.INVOKEVIRTUAL; +import static org.redkale.asm.Opcodes.SIPUSH; + +/** + * ASM简单的工具方法
+ * + *

+ * 详情见: https://redkale.org + * + * @author zhangjx + * + * @since 2.8.0 + */ +public final class Asms { + + private Asms() { + } + + public static void visitAnnotation(final AnnotationVisitor av, final Annotation ann) { + try { + for (Method anm : ann.annotationType().getMethods()) { + final String mname = anm.getName(); + if ("equals".equals(mname) || "hashCode".equals(mname) || "toString".equals(mname) || "annotationType".equals(mname)) { + continue; + } + final Object r = anm.invoke(ann); + if (r instanceof String[]) { + AnnotationVisitor av1 = av.visitArray(mname); + for (String item : (String[]) r) { + av1.visit(null, item); + } + av1.visitEnd(); + } else if (r instanceof Class[]) { + AnnotationVisitor av1 = av.visitArray(mname); + for (Class item : (Class[]) r) { + av1.visit(null, Type.getType(item)); + } + av1.visitEnd(); + } else if (r instanceof Enum[]) { + AnnotationVisitor av1 = av.visitArray(mname); + for (Enum item : (Enum[]) r) { + av1.visitEnum(null, Type.getDescriptor(item.getClass()), ((Enum) item).name()); + } + av1.visitEnd(); + } else if (r instanceof Annotation[]) { + AnnotationVisitor av1 = av.visitArray(mname); + for (Annotation item : (Annotation[]) r) { + visitAnnotation(av1.visitAnnotation(null, Type.getDescriptor(((Annotation) item).annotationType())), item); + } + av1.visitEnd(); + } else if (r instanceof Class) { + av.visit(mname, Type.getType((Class) r)); + } else if (r instanceof Enum) { + av.visitEnum(mname, Type.getDescriptor(r.getClass()), ((Enum) r).name()); + } else if (r instanceof Annotation) { + visitAnnotation(av.visitAnnotation(null, Type.getDescriptor(((Annotation) r).annotationType())), (Annotation) r); + } else { + av.visit(mname, r); + } + } + av.visitEnd(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void visitInsn(MethodVisitor mv, int num) { + if (num < 6) { + mv.visitInsn(ICONST_0 + num); + } else if (num <= Byte.MAX_VALUE) { + mv.visitIntInsn(BIPUSH, num); + } else if (num <= Short.MAX_VALUE) { + mv.visitIntInsn(SIPUSH, num); + } else { + mv.visitLdcInsn(num); + } + } + + public static void visitFieldInsn(MethodVisitor mv, Class clazz) { + if (clazz == boolean.class) { + mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;"); + } else if (clazz == byte.class) { + mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;"); + } else if (clazz == char.class) { + mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;"); + } else if (clazz == short.class) { + mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;"); + } else if (clazz == int.class) { + mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); + } else if (clazz == float.class) { + mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;"); + } else if (clazz == long.class) { + mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;"); + } else if (clazz == double.class) { + mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;"); + } else { + mv.visitLdcInsn(Type.getType(Type.getDescriptor(clazz))); + } + } + + public static void visitPrimitiveValueOf(MethodVisitor mv, Class clazz) { + if (clazz == boolean.class) { + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); + } else if (clazz == byte.class) { + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false); + } else if (clazz == short.class) { + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false); + } else if (clazz == char.class) { + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false); + } else if (clazz == int.class) { + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); + } else if (clazz == float.class) { + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false); + } else if (clazz == long.class) { + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false); + } else if (clazz == double.class) { + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false); + } + } + + public static void visitCheckCast(MethodVisitor mv, Class clazz) { + if (clazz == boolean.class) { + mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false); + } else if (clazz == byte.class) { + mv.visitTypeInsn(CHECKCAST, "java/lang/Byte"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false); + } else if (clazz == short.class) { + mv.visitTypeInsn(CHECKCAST, "java/lang/Short"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false); + } else if (clazz == char.class) { + mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false); + } else if (clazz == int.class) { + mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false); + } else if (clazz == float.class) { + mv.visitTypeInsn(CHECKCAST, "java/lang/Float"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false); + } else if (clazz == long.class) { + mv.visitTypeInsn(CHECKCAST, "java/lang/Long"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false); + } else if (clazz == double.class) { + mv.visitTypeInsn(CHECKCAST, "java/lang/Double"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false); + } else { + mv.visitTypeInsn(CHECKCAST, clazz.getName().replace('.', '/')); + } + } + +} diff --git a/src/main/java/org/redkale/asm/MethodDebugVisitor.java b/src/main/java/org/redkale/asm/MethodDebugVisitor.java index f7223642e..0b17d50a5 100644 --- a/src/main/java/org/redkale/asm/MethodDebugVisitor.java +++ b/src/main/java/org/redkale/asm/MethodDebugVisitor.java @@ -5,10 +5,7 @@ */ package org.redkale.asm; -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; import java.util.*; -import static org.redkale.asm.Opcodes.*; /** * MethodVisitor 的调试类 @@ -17,7 +14,7 @@ import static org.redkale.asm.Opcodes.*; * * @author zhangjx */ -public class MethodDebugVisitor { +public class MethodDebugVisitor extends MethodVisitor { private final MethodVisitor visitor; @@ -29,7 +26,9 @@ public class MethodDebugVisitor { } public void debugLine() { - if (!debug) return; + if (!debug) { + return; + } System.out.println(); System.out.println(); System.out.println(); @@ -43,13 +42,27 @@ public class MethodDebugVisitor { try { for (java.lang.reflect.Field field : Opcodes.class.getFields()) { String name = field.getName(); - if (name.startsWith("ASM")) continue; - if (name.startsWith("V1_")) continue; - if (name.startsWith("ACC_")) continue; - if (name.startsWith("T_")) continue; - if (name.startsWith("H_")) continue; - if (name.startsWith("F_")) continue; - if (field.getType() != int.class) continue; + if (name.startsWith("ASM")) { + continue; + } + if (name.startsWith("V1_")) { + continue; + } + if (name.startsWith("ACC_")) { + continue; + } + if (name.startsWith("T_")) { + continue; + } + if (name.startsWith("H_")) { + continue; + } + if (name.startsWith("F_")) { + continue; + } + if (field.getType() != int.class) { + continue; + } opcodes[(int) (Integer) field.get(null)] = name; } } catch (Exception ex) { @@ -62,41 +75,53 @@ public class MethodDebugVisitor { * @param visitor MethodVisitor */ public MethodDebugVisitor(MethodVisitor visitor) { - //super(Opcodes.ASM5, visitor); + super(Opcodes.ASM6, visitor); this.visitor = visitor; } public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { visitor.visitTryCatchBlock(start, end, handler, type); - if (debug) System.out.println("mv.visitTryCatchBlock(label0, label1, label2, \"" + type + "\");"); + if (debug) { + System.out.println("mv.visitTryCatchBlock(label0, label1, label2, \"" + type + "\");"); + } } public AnnotationVisitor visitParameterAnnotation(int i, String string, boolean bln) { AnnotationVisitor av = visitor.visitParameterAnnotation(i, string, bln); - if (debug) System.out.println("mv.visitParameterAnnotation(" + i + ", \"" + string + "\", " + bln + ");"); + if (debug) { + System.out.println("mv.visitParameterAnnotation(" + i + ", \"" + string + "\", " + bln + ");"); + } return av; } public AnnotationVisitor visitAnnotation(String desc, boolean flag) { AnnotationVisitor av = visitor.visitAnnotation(desc, flag); - if (debug) System.out.println("mv.visitAnnotation(\"" + desc + "\", " + flag + ");"); + if (debug) { + System.out.println("mv.visitAnnotation(\"" + desc + "\", " + flag + ");"); + } return av; } public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { AnnotationVisitor av = visitor.visitTypeAnnotation(typeRef, typePath, desc, visible); - if (debug) System.out.println("mv.visitTypeAnnotation(" + typeRef + ", " + typePath + ", \"" + desc + "\", " + visible + ");"); + if (debug) { + System.out.println("mv.visitTypeAnnotation(" + typeRef + ", " + typePath + ", \"" + desc + "\", " + visible + ");"); + } return av; } public void visitParameter(String name, int access) { visitor.visitParameter(name, access); - if (debug) System.out.println("mv.visitParameter(" + name + ", " + access + ");"); + if (debug) { + System.out.println("mv.visitParameter(" + name + ", " + access + ");"); + } } public void visitVarInsn(int opcode, int var) { visitor.visitVarInsn(opcode, var); - if (debug) System.out.println("mv.visitVarInsn(" + opcodes[opcode] + ", " + var + ");"); + if (debug) { + System.out.println("mv.visitVarInsn(" + opcodes[opcode] + ", " + var + ");"); + } } public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { @@ -133,7 +158,9 @@ public class MethodDebugVisitor { public void visitCode() { visitor.visitCode(); - if (debug) System.out.println("mv.visitCode();"); + if (debug) { + System.out.println("mv.visitCode();"); + } } public void visitLabel(Label var) { @@ -151,32 +178,44 @@ public class MethodDebugVisitor { public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { visitor.visitMethodInsn(opcode, owner, name, desc, itf); - if (debug) System.out.println("mv.visitMethodInsn(" + opcodes[opcode] + ", \"" + owner + "\", \"" + name + "\", \"" + desc + "\", " + itf + ");"); + if (debug) { + System.out.println("mv.visitMethodInsn(" + opcodes[opcode] + ", \"" + owner + "\", \"" + name + "\", \"" + desc + "\", " + itf + ");"); + } } public void visitFieldInsn(int opcode, String owner, String name, String desc) { visitor.visitFieldInsn(opcode, owner, name, desc); - if (debug) System.out.println("mv.visitFieldInsn(" + opcodes[opcode] + ", \"" + owner + "\", \"" + name + "\", \"" + desc + "\");"); + if (debug) { + System.out.println("mv.visitFieldInsn(" + opcodes[opcode] + ", \"" + owner + "\", \"" + name + "\", \"" + desc + "\");"); + } } public void visitTypeInsn(int opcode, String type) { visitor.visitTypeInsn(opcode, type); - if (debug) System.out.println("mv.visitTypeInsn(" + opcodes[opcode] + ", \"" + type + "\");"); + if (debug) { + System.out.println("mv.visitTypeInsn(" + opcodes[opcode] + ", \"" + type + "\");"); + } } public void visitInsn(int opcode) { visitor.visitInsn(opcode); - if (debug) System.out.println("mv.visitInsn(" + opcodes[opcode] + ");"); + if (debug) { + System.out.println("mv.visitInsn(" + opcodes[opcode] + ");"); + } } public void visitIntInsn(int opcode, int value) { visitor.visitIntInsn(opcode, value); - if (debug) System.out.println("mv.visitIntInsn(" + opcodes[opcode] + ", " + value + ");"); + if (debug) { + System.out.println("mv.visitIntInsn(" + opcodes[opcode] + ", " + value + ");"); + } } public void visitIincInsn(int opcode, int value) { visitor.visitIincInsn(opcode, value); - if (debug) System.out.println("mv.visitIincInsn(" + opcode + ", " + value + ");"); + if (debug) { + System.out.println("mv.visitIincInsn(" + opcode + ", " + value + ");"); + } } public void visitLdcInsn(Object o) { @@ -194,81 +233,16 @@ public class MethodDebugVisitor { public void visitMaxs(int maxStack, int maxLocals) { visitor.visitMaxs(maxStack, maxLocals); - if (debug) System.out.println("mv.visitMaxs(" + maxStack + ", " + maxLocals + ");"); + if (debug) { + System.out.println("mv.visitMaxs(" + maxStack + ", " + maxLocals + ");"); + } } public void visitEnd() { visitor.visitEnd(); - if (debug) System.out.println("mv.visitEnd();\r\n\r\n\r\n"); - } - - public static void pushInt(MethodDebugVisitor mv, int num) { - if (num < 6) { - mv.visitInsn(ICONST_0 + num); - } else if (num <= Byte.MAX_VALUE) { - mv.visitIntInsn(BIPUSH, num); - } else if (num <= Short.MAX_VALUE) { - mv.visitIntInsn(SIPUSH, num); - } else { - mv.visitLdcInsn(num); + if (debug) { + System.out.println("mv.visitEnd();\r\n\r\n\r\n"); } } - public static void pushInt(MethodVisitor mv, int num) { - if (num < 6) { - mv.visitInsn(ICONST_0 + num); - } else if (num <= Byte.MAX_VALUE) { - mv.visitIntInsn(BIPUSH, num); - } else if (num <= Short.MAX_VALUE) { - mv.visitIntInsn(SIPUSH, num); - } else { - mv.visitLdcInsn(num); - } - } - - public static void visitAnnotation(final AnnotationVisitor av, final Annotation ann) { - try { - for (Method anm : ann.annotationType().getMethods()) { - final String mname = anm.getName(); - if ("equals".equals(mname) || "hashCode".equals(mname) || "toString".equals(mname) || "annotationType".equals(mname)) continue; - final Object r = anm.invoke(ann); - if (r instanceof String[]) { - AnnotationVisitor av1 = av.visitArray(mname); - for (String item : (String[]) r) { - av1.visit(null, item); - } - av1.visitEnd(); - } else if (r instanceof Class[]) { - AnnotationVisitor av1 = av.visitArray(mname); - for (Class item : (Class[]) r) { - av1.visit(null, Type.getType(item)); - } - av1.visitEnd(); - } else if (r instanceof Enum[]) { - AnnotationVisitor av1 = av.visitArray(mname); - for (Enum item : (Enum[]) r) { - av1.visitEnum(null, Type.getDescriptor(item.getClass()), ((Enum) item).name()); - } - av1.visitEnd(); - } else if (r instanceof Annotation[]) { - AnnotationVisitor av1 = av.visitArray(mname); - for (Annotation item : (Annotation[]) r) { - visitAnnotation(av1.visitAnnotation(null, Type.getDescriptor(((Annotation) item).annotationType())), item); - } - av1.visitEnd(); - } else if (r instanceof Class) { - av.visit(mname, Type.getType((Class) r)); - } else if (r instanceof Enum) { - av.visitEnum(mname, Type.getDescriptor(r.getClass()), ((Enum) r).name()); - } else if (r instanceof Annotation) { - visitAnnotation(av.visitAnnotation(null, Type.getDescriptor(((Annotation) r).annotationType())), (Annotation) r); - } else { - av.visit(mname, r); - } - } - av.visitEnd(); - } catch (Exception e) { - e.printStackTrace(); - } - } } diff --git a/src/main/java/org/redkale/net/http/Rest.java b/src/main/java/org/redkale/net/http/Rest.java index f8b1177b6..34206da0f 100644 --- a/src/main/java/org/redkale/net/http/Rest.java +++ b/src/main/java/org/redkale/net/http/Rest.java @@ -582,15 +582,15 @@ public final class Rest { mv.visitFieldInsn(PUTFIELD, newDynName, "messageRestType", "Ljava/lang/reflect/Type;"); mv.visitVarInsn(ALOAD, 0); - MethodDebugVisitor.pushInt(mv, rws.liveinterval()); + Asms.visitInsn(mv, rws.liveinterval()); mv.visitFieldInsn(PUTFIELD, newDynName, "liveinterval", "I"); mv.visitVarInsn(ALOAD, 0); - MethodDebugVisitor.pushInt(mv, rws.wsmaxconns()); + Asms.visitInsn(mv, rws.wsmaxconns()); mv.visitFieldInsn(PUTFIELD, newDynName, "wsmaxconns", "I"); mv.visitVarInsn(ALOAD, 0); - MethodDebugVisitor.pushInt(mv, rws.wsmaxbody()); + Asms.visitInsn(mv, rws.wsmaxbody()); mv.visitFieldInsn(PUTFIELD, newDynName, "wsmaxbody", "I"); mv.visitVarInsn(ALOAD, 0); @@ -703,12 +703,12 @@ public final class Rest { mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "getNames", "()[Ljava/lang/String;", null, null)); av0 = mv.visitAnnotation(convertDisabledDesc, true); av0.visitEnd(); - MethodDebugVisitor.pushInt(mv, paramap.size()); + Asms.visitInsn(mv, paramap.size()); mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); int index = -1; for (Map.Entry en : paramap.entrySet()) { mv.visitInsn(DUP); - MethodDebugVisitor.pushInt(mv, ++index); + Asms.visitInsn(mv, ++index); mv.visitLdcInsn(en.getKey()); mv.visitInsn(AASTORE); } @@ -1632,7 +1632,7 @@ public final class Rest { throw new RestException(serviceType.getName() + " have illegal " + MessageMultiConsumer.class.getSimpleName() + ".module, only 0-9 a-z A-Z _ - . cannot begin 0-9"); } if (mmc != null) { - MethodDebugVisitor.visitAnnotation(cw.visitAnnotation(Type.getDescriptor(mmc.annotationType()), true), mmc); + Asms.visitAnnotation(cw.visitAnnotation(Type.getDescriptor(mmc.annotationType()), true), mmc); } final Method[] allMethods = serviceType.getMethods(); Arrays.sort(allMethods, (m1, m2) -> { //必须排序,否则paramTypes顺序容易乱 @@ -2796,7 +2796,7 @@ public final class Rest { } else { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_PARAMTYPES_FIELD_NAME, "[[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); int paramidx = -1; for (int i = 0; i < params.length; i++) { @@ -2805,7 +2805,7 @@ public final class Rest { break; } } - MethodDebugVisitor.pushInt(mv, paramidx); //参数下标 + Asms.visitInsn(mv, paramidx); //参数下标 mv.visitInsn(AALOAD); } mv.visitLdcInsn(pname); @@ -3006,7 +3006,7 @@ public final class Rest { mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitMethodInsn(INVOKESTATIC, retInternalName, "success", "()" + retDesc, false); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finishJson", "(" + typeDesc + "Ljava/lang/Object;)V", false); @@ -3112,14 +3112,14 @@ public final class Rest { mv.visitFieldInsn(GETFIELD, newDynName, REST_CONVERT_FIELD_PREFIX + restConverts.size(), convertDesc); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finish", "(" + convertDesc + typeDesc + retDesc + ")V", false); } else { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finish", "(" + typeDesc + retDesc + ")V", false); @@ -3134,14 +3134,14 @@ public final class Rest { mv.visitFieldInsn(GETFIELD, newDynName, REST_CONVERT_FIELD_PREFIX + restConverts.size(), convertDesc); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finish", "(" + convertDesc + typeDesc + httpResultDesc + ")V", false); } else { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finish", "(" + typeDesc + httpResultDesc + ")V", false); @@ -3186,14 +3186,14 @@ public final class Rest { mv.visitFieldInsn(GETFIELD, newDynName, REST_CONVERT_FIELD_PREFIX + restConverts.size(), convertDesc); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finishJsonFuture", "(" + convertDesc + typeDesc + stageDesc + ")V", false); } else { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finishJsonFuture", "(" + typeDesc + stageDesc + ")V", false); @@ -3204,14 +3204,14 @@ public final class Rest { mv.visitFieldInsn(GETFIELD, newDynName, REST_CONVERT_FIELD_PREFIX + restConverts.size(), convertDesc); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finishFuture", "(" + convertDesc + typeDesc + stageDesc + ")V", false); } else { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finishFuture", "(" + typeDesc + stageDesc + ")V", false); @@ -3227,14 +3227,14 @@ public final class Rest { mv.visitFieldInsn(GETFIELD, newDynName, REST_CONVERT_FIELD_PREFIX + restConverts.size(), convertDesc); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finishPublisher", "(" + convertDesc + typeDesc + "Ljava/lang/Object;)V", false); } else { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finishPublisher", "(" + typeDesc + "Ljava/lang/Object;)V", false); @@ -3249,14 +3249,14 @@ public final class Rest { mv.visitFieldInsn(GETFIELD, newDynName, REST_CONVERT_FIELD_PREFIX + restConverts.size(), convertDesc); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finishJson", "(" + convertDesc + typeDesc + "Ljava/lang/Object;)V", false); } else { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finishJson", "(" + typeDesc + "Ljava/lang/Object;)V", false); @@ -3271,14 +3271,14 @@ public final class Rest { mv.visitFieldInsn(GETFIELD, newDynName, REST_CONVERT_FIELD_PREFIX + restConverts.size(), convertDesc); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finish", "(" + convertDesc + typeDesc + "Ljava/lang/Object;)V", false); } else { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, REST_RETURNTYPES_FIELD_NAME, "[Ljava/lang/reflect/Type;"); - MethodDebugVisitor.pushInt(mv, entry.methodIdx);//方法下标 + Asms.visitInsn(mv, entry.methodIdx);//方法下标 mv.visitInsn(AALOAD); mv.visitVarInsn(ALOAD, maxLocals); mv.visitMethodInsn(INVOKEVIRTUAL, respInternalName, "finish", "(" + typeDesc + "Ljava/lang/Object;)V", false); @@ -3321,7 +3321,7 @@ public final class Rest { // mv = new MethodDebugVisitor(cw2.visitMethod(ACC_SYNTHETIC, "", "(L" + newDynName + ";L" + newDynName + "$" + entry.newActionClassName + ";)V", null, null)); // mv.visitVarInsn(ALOAD, 0); // mv.visitVarInsn(ALOAD, 1); -// mv.visitMethodInsn(INVOKESPECIAL, newDynName + "$" + entry.newActionClassName, "", "L" + newDynName + ";", false); +// mv.visitCheckCast(INVOKESPECIAL, newDynName + "$" + entry.newActionClassName, "", "L" + newDynName + ";", false); // mv.visitInsn(RETURN); // mv.visitMaxs(2, 3); // mv.visitEnd(); @@ -3372,21 +3372,21 @@ public final class Rest { mv.visitLdcInsn(entry.mappingurl); //name mv.visitTypeInsn(NEW, actionEntryName); //new ActionEntry mv.visitInsn(DUP); - MethodDebugVisitor.pushInt(mv, moduleid); //moduleid - MethodDebugVisitor.pushInt(mv, entry.actionid); //actionid + Asms.visitInsn(mv, moduleid); //moduleid + Asms.visitInsn(mv, entry.actionid); //actionid mv.visitLdcInsn(entry.mappingurl); //name - MethodDebugVisitor.pushInt(mv, entry.methods.length); //methods + Asms.visitInsn(mv, entry.methods.length); //methods mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); for (int i = 0; i < entry.methods.length; i++) { mv.visitInsn(DUP); - MethodDebugVisitor.pushInt(mv, i); + Asms.visitInsn(mv, i); mv.visitLdcInsn(entry.methods[i]); mv.visitInsn(AASTORE); } mv.visitInsn(ACONST_NULL); //method mv.visitInsn(entry.rpconly ? ICONST_1 : ICONST_0); //rpconly mv.visitInsn(entry.auth ? ICONST_1 : ICONST_0); //auth - MethodDebugVisitor.pushInt(mv, entry.cacheSeconds); //cacheSeconds + Asms.visitInsn(mv, entry.cacheSeconds); //cacheSeconds mv.visitTypeInsn(NEW, newDynName + "$" + entry.newActionClassName); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); diff --git a/src/main/java/org/redkale/net/sncp/Sncp.java b/src/main/java/org/redkale/net/sncp/Sncp.java index e5006a34d..f91f54f90 100644 --- a/src/main/java/org/redkale/net/sncp/Sncp.java +++ b/src/main/java/org/redkale/net/sncp/Sncp.java @@ -481,7 +481,7 @@ public abstract class Sncp { if (ann instanceof Resource || ann instanceof SncpDyn || ann instanceof ResourceType) { continue; } - MethodDebugVisitor.visitAnnotation(cw.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann); + Asms.visitAnnotation(cw.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann); } } { @@ -765,7 +765,7 @@ public abstract class Sncp { if (ann instanceof Resource || ann instanceof SncpDyn || ann instanceof ResourceType) { continue; } - MethodDebugVisitor.visitAnnotation(cw.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann); + Asms.visitAnnotation(cw.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann); } } { @@ -808,14 +808,14 @@ public abstract class Sncp { // Label l1 = new Label(); // mv.visitJumpInsn(IFNONNULL, l1); // mv.visitVarInsn(ALOAD, 0); -// mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false); -// mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;", false); +// mv.visitCheckCast(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false); +// mv.visitCheckCast(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;", false); // Label l2 = new Label(); // mv.visitJumpInsn(GOTO, l2); // mv.visitLabel(l1); // mv.visitVarInsn(ALOAD, 0); // mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_sncp", sncpInfoDesc); -// mv.visitMethodInsn(INVOKEVIRTUAL, sncpInfoName, "toSimpleString", "()Ljava/lang/String;", false); +// mv.visitCheckCast(INVOKEVIRTUAL, sncpInfoName, "toSimpleString", "()Ljava/lang/String;", false); // mv.visitLabel(l2); // mv.visitInsn(ARETURN); // mv.visitMaxs(1, 1); @@ -830,7 +830,7 @@ public abstract class Sncp { final Annotation[][] anns = method.getParameterAnnotations(); for (int k = 0; k < anns.length; k++) { for (Annotation ann : anns[k]) { - MethodDebugVisitor.visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann); + Asms.visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann); } } } @@ -841,7 +841,7 @@ public abstract class Sncp { { //传参数 int paramlen = entry.paramTypes.length; - MethodDebugVisitor.pushInt(mv, paramlen); + Asms.visitInsn(mv, paramlen); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); java.lang.reflect.Type[] paramtypes = entry.paramTypes; int insn = 0; @@ -849,7 +849,7 @@ public abstract class Sncp { final java.lang.reflect.Type pt = paramtypes[j]; mv.visitInsn(DUP); insn++; - MethodDebugVisitor.pushInt(mv, j); + Asms.visitInsn(mv, j); if (pt instanceof Class && ((Class) pt).isPrimitive()) { if (pt == long.class) { mv.visitVarInsn(LLOAD, insn++); @@ -870,7 +870,7 @@ public abstract class Sncp { } mv.visitMethodInsn(INVOKEVIRTUAL, sncpInfoName, "remote", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;", false); - //mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false); + //mv.visitCheckCast(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false); if (method.getGenericReturnType() == void.class) { mv.visitInsn(POP); mv.visitInsn(RETURN); diff --git a/src/main/java/org/redkale/util/Attribute.java b/src/main/java/org/redkale/util/Attribute.java index d4b6c5d40..25635dbe1 100644 --- a/src/main/java/org/redkale/util/Attribute.java +++ b/src/main/java/org/redkale/util/Attribute.java @@ -698,9 +698,7 @@ public interface Attribute { int mod = field == null ? java.lang.reflect.Modifier.STATIC : field.getModifiers(); if (field != null && !java.lang.reflect.Modifier.isStatic(mod) && !java.lang.reflect.Modifier.isPublic(mod)) { Class t = field.getType(); - char[] fs = field.getName().toCharArray(); - fs[0] = Character.toUpperCase(fs[0]); - String mn = new String(fs); + String mn = Utility.firstCharUpperCase(field.getName()); if (getter == null) { String prefix = t == boolean.class || t == Boolean.class ? "is" : "get"; try { @@ -877,25 +875,7 @@ public interface Attribute { } { //type 方法 mv = cw.visitMethod(ACC_PUBLIC, "type", "()Ljava/lang/Class;", null, null); - if (pcolumn == boolean.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == byte.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == char.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == short.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == int.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == float.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == long.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == double.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;"); - } else { - mv.visitLdcInsn(Type.getType(pcolumn)); - } + Asms.visitFieldInsn(mv, pcolumn); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); diff --git a/src/main/java/org/redkale/util/Copier.java b/src/main/java/org/redkale/util/Copier.java index 55543881f..c58abefa5 100644 --- a/src/main/java/org/redkale/util/Copier.java +++ b/src/main/java/org/redkale/util/Copier.java @@ -9,7 +9,32 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.*; import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES; import org.redkale.asm.*; -import static org.redkale.asm.Opcodes.*; +import static org.redkale.asm.Opcodes.ACC_BRIDGE; +import static org.redkale.asm.Opcodes.ACC_FINAL; +import static org.redkale.asm.Opcodes.ACC_PRIVATE; +import static org.redkale.asm.Opcodes.ACC_PUBLIC; +import static org.redkale.asm.Opcodes.ACC_STATIC; +import static org.redkale.asm.Opcodes.ACC_SUPER; +import static org.redkale.asm.Opcodes.ACC_SYNTHETIC; +import static org.redkale.asm.Opcodes.ALOAD; +import static org.redkale.asm.Opcodes.ARETURN; +import static org.redkale.asm.Opcodes.ASTORE; +import static org.redkale.asm.Opcodes.CHECKCAST; +import static org.redkale.asm.Opcodes.GETFIELD; +import static org.redkale.asm.Opcodes.GETSTATIC; +import static org.redkale.asm.Opcodes.GOTO; +import static org.redkale.asm.Opcodes.IFEQ; +import static org.redkale.asm.Opcodes.IFLE; +import static org.redkale.asm.Opcodes.IFNULL; +import static org.redkale.asm.Opcodes.INSTANCEOF; +import static org.redkale.asm.Opcodes.INVOKEINTERFACE; +import static org.redkale.asm.Opcodes.INVOKESPECIAL; +import static org.redkale.asm.Opcodes.INVOKESTATIC; +import static org.redkale.asm.Opcodes.INVOKEVIRTUAL; +import static org.redkale.asm.Opcodes.POP; +import static org.redkale.asm.Opcodes.PUTFIELD; +import static org.redkale.asm.Opcodes.RETURN; +import static org.redkale.asm.Opcodes.V11; import org.redkale.asm.Type; /** @@ -21,19 +46,26 @@ import org.redkale.asm.Type; * @author zhangjx * @param 目标对象的数据类型 * @param 源对象的数据类型 + * + * @since 2.8.0 */ public interface Copier extends BiFunction { /** - * bean复制到map时,是否跳过值为null的字段 + * 是否跳过值为null的字段 */ public static final int OPTION_SKIP_NULL_VALUE = 1 << 1; //2 /** - * bean复制到map时,是否跳过值为空字符串的字段 + * 是否跳过值为空字符串的字段 */ public static final int OPTION_SKIP_RMPTY_STRING = 1 << 2; //4 + /** + * 同名字段类型强制转换 + */ + public static final int OPTION_ALLOW_TYPE_CAST = 1 << 3; //8 + /** * 将源对象字段复制到目标对象 * @@ -288,22 +320,23 @@ public interface Copier extends BiFunction { * @param srcClass 源类名 * @param options 可配项 * @param srcColumnPredicate 需复制的字段名判断期 - * @param names 源字段名与目标字段名的映射关系 + * @param nameAlias 源字段名与目标字段名的映射关系 * * @return 复制器 */ @SuppressWarnings("unchecked") public static Copier create(final Class srcClass, final Class destClass, final int options, - final BiPredicate srcColumnPredicate, final Map names) { + final BiPredicate srcColumnPredicate, final Map nameAlias) { final boolean skipNullValue = (options & OPTION_SKIP_NULL_VALUE) > 0 || ConcurrentHashMap.class.isAssignableFrom(destClass); final boolean skipEmptyString = (options & OPTION_SKIP_RMPTY_STRING) > 0; + final boolean allowTypeCast = (options & OPTION_ALLOW_TYPE_CAST) > 0; final Predicate valPredicate = v -> !(skipNullValue && v == null) && !(skipEmptyString && v instanceof CharSequence && ((CharSequence) v).length() == 0); if (Map.class.isAssignableFrom(destClass) && Map.class.isAssignableFrom(srcClass)) { - final Map names0 = names; + final Map names0 = nameAlias; if (srcColumnPredicate != null) { - if (names != null) { + if (nameAlias != null) { return (S src, D dest) -> { Map d = (Map) dest; ((Map) src).forEach((k, v) -> { @@ -324,7 +357,7 @@ public interface Copier extends BiFunction { return dest; }; } - } else if (names != null) { + } else if (nameAlias != null) { return (S src, D dest) -> { Map d = (Map) dest; ((Map) src).forEach((k, v) -> { @@ -388,7 +421,7 @@ public interface Copier extends BiFunction { mv.visitMaxs(1, 1); mv.visitEnd(); } - if (srcIsMap) { //destClass不是Map + if (srcIsMap) { //Map -> JavaBean { mv = (cw.visitMethod(ACC_PUBLIC, "apply", "(" + srcDesc + destDesc + ")" + destDesc, null, null)); //mv.setDebug(true); @@ -420,7 +453,7 @@ public interface Copier extends BiFunction { if (srcColumnPredicate != null && !srcColumnPredicate.test(field, sfname)) { continue; } - final String dfname = names == null ? sfname : names.getOrDefault(sfname, sfname); + final String dfname = nameAlias == null ? sfname : nameAlias.getOrDefault(sfname, sfname); elements.put(dfname, field); } @@ -444,7 +477,7 @@ public interface Copier extends BiFunction { if (srcColumnPredicate != null && !srcColumnPredicate.test(setter, sfname)) { continue; } - final String dfname = names == null ? sfname : names.getOrDefault(sfname, sfname); + final String dfname = nameAlias == null ? sfname : nameAlias.getOrDefault(sfname, sfname); elements.put(dfname, setter); } @@ -483,55 +516,11 @@ public interface Copier extends BiFunction { } mv.visitVarInsn(ALOAD, 0); - if (fieldClass == boolean.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;"); - } else if (fieldClass == byte.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;"); - } else if (fieldClass == char.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;"); - } else if (fieldClass == short.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;"); - } else if (fieldClass == int.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); - } else if (fieldClass == float.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;"); - } else if (fieldClass == long.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;"); - } else if (fieldClass == double.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;"); - } else { - mv.visitLdcInsn(Type.getType(Type.getDescriptor(fieldClass))); - } + Asms.visitFieldInsn(mv, fieldClass); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKESTATIC, utilClassName, "convertValue", "(Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;", false); - if (fieldClass == boolean.class) { - mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false); - } else if (fieldClass == byte.class) { - mv.visitTypeInsn(CHECKCAST, "java/lang/Byte"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false); - } else if (fieldClass == short.class) { - mv.visitTypeInsn(CHECKCAST, "java/lang/Short"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false); - } else if (fieldClass == char.class) { - mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false); - } else if (fieldClass == int.class) { - mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false); - } else if (fieldClass == float.class) { - mv.visitTypeInsn(CHECKCAST, "java/lang/Float"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false); - } else if (fieldClass == long.class) { - mv.visitTypeInsn(CHECKCAST, "java/lang/Long"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false); - } else if (fieldClass == double.class) { - mv.visitTypeInsn(CHECKCAST, "java/lang/Double"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false); - } else { - mv.visitTypeInsn(CHECKCAST, fieldClass.getName().replace('.', '/')); - } + Asms.visitCheckCast(mv, fieldClass); if (en.getValue() instanceof Field) { mv.visitFieldInsn(PUTFIELD, destClassName, en.getKey(), Type.getDescriptor(fieldClass)); @@ -552,7 +541,7 @@ public interface Copier extends BiFunction { mv.visitMaxs(3, 3); mv.visitEnd(); } - } else { //srcClass是JavaBean + } else { //JavaBean -> Map/JavaBean mv = (cw.visitMethod(ACC_PUBLIC, "apply", "(" + srcDesc + destDesc + ")" + destDesc, null, null)); //mv.setDebug(true); @@ -571,33 +560,17 @@ public interface Copier extends BiFunction { continue; } - final String dfname = names == null ? sfname : names.getOrDefault(sfname, sfname); - final Class st = field.getType(); - final boolean charstr = CharSequence.class.isAssignableFrom(st); - if (destIsMap) { //srcClass是JavaBean - String td = Type.getDescriptor(st); - if ((!skipNullValue && !(skipEmptyString && charstr)) || st.isPrimitive()) { + final String dfname = nameAlias == null ? sfname : nameAlias.getOrDefault(sfname, sfname); + final Class srcFieldType = field.getType(); + final boolean charstr = CharSequence.class.isAssignableFrom(srcFieldType); + if (destIsMap) { //JavaBean -> Map + String td = Type.getDescriptor(srcFieldType); + if ((!skipNullValue && !(skipEmptyString && charstr)) || srcFieldType.isPrimitive()) { mv.visitVarInsn(ALOAD, 2); mv.visitLdcInsn(dfname); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, srcClassName, sfname, td); - if (st == boolean.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); - } else if (st == byte.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false); - } else if (st == short.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false); - } else if (st == char.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false); - } else if (st == int.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); - } else if (st == float.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false); - } else if (st == long.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false); - } else if (st == double.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false); - } + Asms.visitPrimitiveValueOf(mv, srcFieldType); mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", destClass.isInterface()); mv.visitInsn(POP); } else { // skipNullValue OR (skipEmptyString && charstr) @@ -621,35 +594,88 @@ public interface Copier extends BiFunction { mv.visitLabel(ifLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } - } else { + } else { //JavaBean -> JavaBean + boolean needTypeCast = false; java.lang.reflect.Method setter = null; + java.lang.reflect.Field setField = null; try { - if (!field.getType().equals(destClass.getField(dfname).getType())) { - continue; + setField = destClass.getField(dfname); + if (!field.getType().equals(setField.getType())) { + if (allowTypeCast) { + needTypeCast = true; + } else { + continue; + } } } catch (Exception e) { + String setterMethodName = "set" + Utility.firstCharUpperCase(dfname); try { - char[] cs = dfname.toCharArray(); - cs[0] = Character.toUpperCase(cs[0]); - String dfname2 = new String(cs); - setter = destClass.getMethod("set" + dfname2, field.getType()); + setter = destClass.getMethod(setterMethodName, field.getType()); + if (Utility.contains(setter.getExceptionTypes(), throwPredicate)) { + continue; //setter方法带有非RuntimeException异常 + } } catch (Exception e2) { - continue; + if (allowTypeCast) { + try { + for (java.lang.reflect.Method m : destClass.getMethods()) { + if (Modifier.isStatic(m.getModifiers())) { + continue; + } + if (Utility.contains(m.getExceptionTypes(), throwPredicate)) { + continue; //setter方法带有非RuntimeException异常 + } + if (m.getParameterTypes().length != 1) { + continue; + } + if (m.getName().equals(setterMethodName)) { + setter = m; + needTypeCast = true; + break; + } + } + if (setter == null) { + continue; + } + } catch (Exception e3) { + continue; + } + } else { + continue; + } } } - String td = Type.getDescriptor(st); - if ((!skipNullValue && !(skipEmptyString && charstr)) || st.isPrimitive()) { - mv.visitVarInsn(ALOAD, 2); - mv.visitVarInsn(ALOAD, 1); - mv.visitFieldInsn(GETFIELD, srcClassName, sfname, td); - if (setter == null) { - mv.visitFieldInsn(PUTFIELD, destClassName, dfname, td); + String srcFieldDesc = Type.getDescriptor(srcFieldType); + final Class destFieldType = setter == null ? setField.getType() : setter.getParameterTypes()[0]; + boolean localSkipNull = skipNullValue || (!srcFieldType.isPrimitive() && destFieldType.isPrimitive()); + if ((!localSkipNull && !(skipEmptyString && charstr)) + || (srcFieldType.isPrimitive() && !allowTypeCast) + || (srcFieldType.isPrimitive() && destFieldType.isPrimitive())) { + if (needTypeCast) { + mv.visitVarInsn(ALOAD, 2); + Asms.visitFieldInsn(mv, destFieldType); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(GETFIELD, srcClassName, sfname, srcFieldDesc); + Asms.visitPrimitiveValueOf(mv, srcFieldType); + mv.visitMethodInsn(INVOKESTATIC, utilClassName, "convertValue", "(Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;", false); + Asms.visitCheckCast(mv, destFieldType); + if (setter == null) { //src: field, dest:field + mv.visitFieldInsn(PUTFIELD, destClassName, dfname, Type.getDescriptor(destFieldType)); + } else { //src: field, dest:method + mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, setter.getName(), Type.getMethodDescriptor(setter), destClass.isInterface()); + } } else { - mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, setter.getName(), Type.getMethodDescriptor(setter), destClass.isInterface()); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(GETFIELD, srcClassName, sfname, srcFieldDesc); + if (setter == null) { //src: field, dest:field + mv.visitFieldInsn(PUTFIELD, destClassName, dfname, Type.getDescriptor(destFieldType)); + } else { //src: field, dest:method + mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, setter.getName(), Type.getMethodDescriptor(setter), destClass.isInterface()); + } } } else { // skipNullValue OR (skipEmptyString && charstr) mv.visitVarInsn(ALOAD, 1); - mv.visitFieldInsn(GETFIELD, srcClassName, sfname, td); + mv.visitFieldInsn(GETFIELD, srcClassName, sfname, srcFieldDesc); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 3); Label ifLabel = new Label(); @@ -660,13 +686,27 @@ public interface Copier extends BiFunction { mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/CharSequence", "length", "()I", true); mv.visitJumpInsn(IFLE, ifLabel); } - mv.visitVarInsn(ALOAD, 2); - mv.visitVarInsn(ALOAD, 3); - mv.visitTypeInsn(CHECKCAST, st.getName().replace('.', '/')); - if (setter == null) { - mv.visitFieldInsn(PUTFIELD, destClassName, dfname, td); + if (needTypeCast) { + mv.visitVarInsn(ALOAD, 2); + Asms.visitFieldInsn(mv, destFieldType); + mv.visitVarInsn(ALOAD, 3); + Asms.visitPrimitiveValueOf(mv, srcFieldType); + mv.visitMethodInsn(INVOKESTATIC, utilClassName, "convertValue", "(Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;", false); + Asms.visitCheckCast(mv, destFieldType); + if (setter == null) { //src: field, dest:field + mv.visitFieldInsn(PUTFIELD, destClassName, dfname, Type.getDescriptor(destFieldType)); + } else { //src: field, dest:method + mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, setter.getName(), Type.getMethodDescriptor(setter), destClass.isInterface()); + } } else { - mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, setter.getName(), Type.getMethodDescriptor(setter), destClass.isInterface()); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 3); + mv.visitTypeInsn(CHECKCAST, srcFieldType.getName().replace('.', '/')); + if (setter == null) { //src: field, dest:field + mv.visitFieldInsn(PUTFIELD, destClassName, dfname, srcFieldDesc); + } else { //src: field, dest:method + mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, setter.getName(), Type.getMethodDescriptor(setter), destClass.isInterface()); + } } mv.visitLabel(ifLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); @@ -698,32 +738,16 @@ public interface Copier extends BiFunction { continue; } - final String dfname = names == null ? sfname : names.getOrDefault(sfname, sfname); - final Class st = getter.getReturnType(); - final boolean charstr = CharSequence.class.isAssignableFrom(st); + final String dfname = nameAlias == null ? sfname : nameAlias.getOrDefault(sfname, sfname); + final Class srcFieldType = getter.getReturnType(); + final boolean charstr = CharSequence.class.isAssignableFrom(srcFieldType); if (destIsMap) { //srcClass是JavaBean - if ((!skipNullValue && !(skipEmptyString && charstr)) || st.isPrimitive()) { + if ((!skipNullValue && !(skipEmptyString && charstr)) || srcFieldType.isPrimitive()) { mv.visitVarInsn(ALOAD, 2); mv.visitLdcInsn(dfname); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(srcClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, srcClassName, getter.getName(), Type.getMethodDescriptor(getter), srcClass.isInterface()); - if (st == boolean.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); - } else if (st == byte.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false); - } else if (st == short.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false); - } else if (st == char.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false); - } else if (st == int.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); - } else if (st == float.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false); - } else if (st == long.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false); - } else if (st == double.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false); - } + Asms.visitPrimitiveValueOf(mv, srcFieldType); mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", destClass.isInterface()); mv.visitInsn(POP); } else { // skipNullValue OR (skipEmptyString && charstr) @@ -747,35 +771,80 @@ public interface Copier extends BiFunction { mv.visitLabel(ifLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } - } else { + } else { //srcClass、destClass是JavaBean + boolean needTypeCast = false; java.lang.reflect.Method setter = null; - java.lang.reflect.Field srcField = null; - char[] cs = dfname.toCharArray(); - cs[0] = Character.toUpperCase(cs[0]); - String dfname2 = new String(cs); + java.lang.reflect.Field setField = null; + String setterMethodName = "set" + Utility.firstCharUpperCase(dfname); try { - setter = destClass.getMethod("set" + dfname2, getter.getReturnType()); + setter = destClass.getMethod(setterMethodName, getter.getReturnType()); if (Utility.contains(setter.getExceptionTypes(), throwPredicate)) { continue; //setter方法带有非RuntimeException异常 } } catch (Exception e) { - try { - srcField = destClass.getField(dfname); - if (!getter.getReturnType().equals(srcField.getType())) { + if (allowTypeCast) { + try { + for (java.lang.reflect.Method m : destClass.getMethods()) { + if (Modifier.isStatic(m.getModifiers())) { + continue; + } + if (Utility.contains(m.getExceptionTypes(), throwPredicate)) { + continue; //setter方法带有非RuntimeException异常 + } + if (m.getParameterTypes().length != 1) { + continue; + } + if (m.getName().equals(setterMethodName)) { + setter = m; + needTypeCast = true; + break; + } + } + } catch (Exception e2) { + } + } + if (setter == null) { + try { + setField = destClass.getField(dfname); + if (!getter.getReturnType().equals(setField.getType())) { + if (allowTypeCast) { + needTypeCast = true; + } else { + continue; + } + } + } catch (Exception e3) { continue; } - } catch (Exception e2) { - continue; } } - if ((!skipNullValue && !(skipEmptyString && charstr)) || st.isPrimitive()) { - mv.visitVarInsn(ALOAD, 2); - mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(srcClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, srcClassName, getter.getName(), Type.getMethodDescriptor(getter), srcClass.isInterface()); - if (srcField == null) { - mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, setter.getName(), Type.getMethodDescriptor(setter), destClass.isInterface()); + final Class destFieldType = setter == null ? setField.getType() : setter.getParameterTypes()[0]; + boolean localSkipNull = skipNullValue || (!srcFieldType.isPrimitive() && destFieldType.isPrimitive()); + if ((!localSkipNull && !(skipEmptyString && charstr)) + || (srcFieldType.isPrimitive() && !allowTypeCast) + || (srcFieldType.isPrimitive() && destFieldType.isPrimitive())) { + if (needTypeCast) { + mv.visitVarInsn(ALOAD, 2); + Asms.visitFieldInsn(mv, destFieldType); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(srcClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, srcClassName, getter.getName(), Type.getMethodDescriptor(getter), srcClass.isInterface()); + Asms.visitPrimitiveValueOf(mv, srcFieldType); + mv.visitMethodInsn(INVOKESTATIC, utilClassName, "convertValue", "(Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;", false); + Asms.visitCheckCast(mv, destFieldType); + if (setter == null) { //src: method, dest: field + mv.visitFieldInsn(PUTFIELD, destClassName, dfname, Type.getDescriptor(destFieldType)); + } else { //src: method, dest: method + mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, setter.getName(), Type.getMethodDescriptor(setter), destClass.isInterface()); + } } else { - mv.visitFieldInsn(PUTFIELD, destClassName, dfname, Type.getDescriptor(getter.getReturnType())); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(srcClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, srcClassName, getter.getName(), Type.getMethodDescriptor(getter), srcClass.isInterface()); + if (setter == null) { //src: method, dest: field + mv.visitFieldInsn(PUTFIELD, destClassName, dfname, Type.getDescriptor(destFieldType)); + } else { //src: method, dest: method + mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, setter.getName(), Type.getMethodDescriptor(setter), destClass.isInterface()); + } } } else { // skipNullValue OR (skipEmptyString && charstr) mv.visitVarInsn(ALOAD, 1); @@ -790,13 +859,46 @@ public interface Copier extends BiFunction { mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/CharSequence", "length", "()I", true); mv.visitJumpInsn(IFLE, ifLabel); } - mv.visitVarInsn(ALOAD, 2); - mv.visitVarInsn(ALOAD, 3); - mv.visitTypeInsn(CHECKCAST, st.getName().replace('.', '/')); - if (srcField == null) { - mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, setter.getName(), Type.getMethodDescriptor(setter), destClass.isInterface()); + if (false) { + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/test/util/TestBean", "getName", "()Ljava/lang/String;", false); + mv.visitVarInsn(ASTORE, 3); + mv.visitVarInsn(ALOAD, 3); + mv.visitJumpInsn(IFNULL, ifLabel); + + + mv.visitVarInsn(ALOAD, 2); + mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;"); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKESTATIC, "org/redkale/util/Utility", "convertValue", "(Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;", false); + mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/test/util/TestXBean", "setId", "(I)V", false); + mv.visitLabel(ifLabel); + mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + } + + if (needTypeCast) { + mv.visitVarInsn(ALOAD, 2); + Asms.visitFieldInsn(mv, destFieldType); + mv.visitVarInsn(ALOAD, 3); + Asms.visitPrimitiveValueOf(mv, srcFieldType); + mv.visitMethodInsn(INVOKESTATIC, utilClassName, "convertValue", "(Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;", false); + Asms.visitCheckCast(mv, destFieldType); + if (setter == null) { //src: method, dest: field + mv.visitFieldInsn(PUTFIELD, destClassName, dfname, Type.getDescriptor(destFieldType)); + } else { //src: method, dest: method + mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, setter.getName(), Type.getMethodDescriptor(setter), destClass.isInterface()); + } } else { - mv.visitFieldInsn(PUTFIELD, destClassName, dfname, Type.getDescriptor(getter.getReturnType())); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 3); + mv.visitTypeInsn(CHECKCAST, srcFieldType.getName().replace('.', '/')); + if (setter == null) { //src: method, dest: field + mv.visitFieldInsn(PUTFIELD, destClassName, dfname, Type.getDescriptor(getter.getReturnType())); + } else { //src: method, dest: method + mv.visitMethodInsn(destClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, destClassName, setter.getName(), Type.getMethodDescriptor(setter), destClass.isInterface()); + } } mv.visitLabel(ifLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); diff --git a/src/main/java/org/redkale/util/Creator.java b/src/main/java/org/redkale/util/Creator.java index 41f2b11b5..6a409f358 100644 --- a/src/main/java/org/redkale/util/Creator.java +++ b/src/main/java/org/redkale/util/Creator.java @@ -388,25 +388,7 @@ public interface Creator { } else { mv.visitLdcInsn(i); } - if (pt == boolean.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;"); - } else if (pt == byte.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;"); - } else if (pt == char.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;"); - } else if (pt == short.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;"); - } else if (pt == int.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); - } else if (pt == float.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;"); - } else if (pt == long.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;"); - } else if (pt == double.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;"); - } else { - mv.visitLdcInsn(Type.getType(Type.getDescriptor(pt))); - } + Asms.visitFieldInsn(mv, pt); mv.visitInsn(AASTORE); } mv.visitInsn(ARETURN); diff --git a/src/main/java/org/redkale/util/Invoker.java b/src/main/java/org/redkale/util/Invoker.java index b5ae8f790..ec6818cb7 100644 --- a/src/main/java/org/redkale/util/Invoker.java +++ b/src/main/java/org/redkale/util/Invoker.java @@ -135,7 +135,7 @@ public interface Invoker { for (Class paramType : method.getParameterTypes()) { //参数 mv.visitVarInsn(ALOAD, 2); - MethodDebugVisitor.pushInt(mv, paramIndex); + Asms.visitInsn(mv, paramIndex); mv.visitInsn(AALOAD); if (paramType == boolean.class) { paramDescs.append("Z"); @@ -179,23 +179,7 @@ public interface Invoker { } mv.visitMethodInsn(staticflag ? INVOKESTATIC : (clazz.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL), interName, method.getName(), "(" + paramDescs + ")" + returnPrimiveDesc, !staticflag && clazz.isInterface()); - if (returnType == boolean.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); - } else if (returnType == byte.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false); - } else if (returnType == short.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false); - } else if (returnType == char.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false); - } else if (returnType == int.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); - } else if (returnType == float.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false); - } else if (returnType == long.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false); - } else if (returnType == double.class) { - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false); - } + Asms.visitPrimitiveValueOf(mv, returnType); mv.visitLabel(label1); mv.visitInsn(ARETURN); if (throwflag) { diff --git a/src/main/java/org/redkale/util/Utility.java b/src/main/java/org/redkale/util/Utility.java index 8f597a801..3522ea486 100644 --- a/src/main/java/org/redkale/util/Utility.java +++ b/src/main/java/org/redkale/util/Utility.java @@ -7,6 +7,7 @@ package org.redkale.util; import java.io.*; import java.lang.invoke.*; import java.lang.reflect.*; +import java.math.*; import java.net.*; import java.net.http.HttpClient; import java.nio.*; @@ -2704,22 +2705,32 @@ public final class Utility { } else if (clazz == double.class || clazz == Double.class) { if (value instanceof Number) { return (T) (Number) ((Number) value).doubleValue(); + } else if (vclzz == String.class) { + return (T) (Number) Double.parseDouble(value.toString()); } } else if (clazz == float.class || clazz == Float.class) { if (value instanceof Number) { return (T) (Number) ((Number) value).floatValue(); + } else if (vclzz == String.class) { + return (T) (Number) Float.parseFloat(value.toString()); } } else if (clazz == long.class || clazz == Long.class) { if (value instanceof Number) { return (T) (Number) ((Number) value).longValue(); + } else if (vclzz == String.class) { + return (T) (Number) Long.parseLong(value.toString()); } } else if (clazz == int.class || clazz == Integer.class) { if (value instanceof Number) { return (T) (Number) ((Number) value).intValue(); + } else if (vclzz == String.class) { + return (T) (Number) Integer.parseInt(value.toString()); } } else if (clazz == short.class || clazz == Short.class) { if (value instanceof Number) { return (T) (Number) ((Number) value).shortValue(); + } else if (vclzz == String.class) { + return (T) (Number) Short.parseShort(value.toString()); } } else if (clazz == char.class || clazz == Character.class) { if (value instanceof Number) { @@ -2734,6 +2745,10 @@ public final class Utility { if (value instanceof Number) { return (T) (Object) (((Number) value).intValue() > 0); } + } else if (clazz == BigInteger.class && vclzz == String.class) { + return (T) new BigInteger(value.toString()); + } else if (clazz == BigDecimal.class && vclzz == String.class) { + return (T) new BigDecimal(value.toString()); } JsonConvert convert = JsonConvert.root(); if (CharSequence.class.isAssignableFrom(vclzz)) { diff --git a/src/test/java/org/redkale/test/util/CopierTest.java b/src/test/java/org/redkale/test/util/CopierTest.java index e2c0df24b..97449d5a0 100644 --- a/src/test/java/org/redkale/test/util/CopierTest.java +++ b/src/test/java/org/redkale/test/util/CopierTest.java @@ -29,6 +29,12 @@ public class CopierTest { test.run10(); test.run11(); test.run12(); + test.run13(); + test.run14(); + test.run15(); + test.run16(); + test.run17(); + test.run18(); } @Test @@ -42,6 +48,7 @@ public class CopierTest { System.out.println(JsonConvert.root().convertTo(map)); TreeMap rs = Copier.copy(bean, TreeMap.class); rs.remove("remark"); + rs.remove("seqno"); Assertions.assertEquals(bean.toString(), JsonConvert.root().convertTo(rs)); } @@ -206,4 +213,144 @@ public class CopierTest { System.out.println(JsonConvert.root().convertTo(bean)); Assertions.assertTrue(bean.getName() == null); } + + @Test + public void run13() throws Exception { + TestBean bean = new TestBean(); + bean.setSeqno(6666L); + //public String remark; + //private Long seqno; + TestX2Bean destBean = new TestX2Bean(); + //public int remark; + //private String seqno; + + Copier.load(TestBean.class, TestX2Bean.class, Copier.OPTION_ALLOW_TYPE_CAST).apply(bean, destBean); + System.out.println(JsonConvert.root().convertTo(destBean)); + Assertions.assertEquals("6666", destBean.getSeqno()); + } + + @Test + public void run14() throws Exception { + TestBean bean = new TestBean(); + bean.remark = "444"; + TestX2Bean destBean = new TestX2Bean(); + Copier.load(TestBean.class, TestX2Bean.class, Copier.OPTION_SKIP_NULL_VALUE | Copier.OPTION_ALLOW_TYPE_CAST).apply(bean, destBean); + System.out.println(JsonConvert.root().convertTo(destBean)); + Assertions.assertTrue(destBean.remark == 444); + } + + @Test + public void run15() throws Exception { + Bean1 bean1 = new Bean1(); + bean1.intval = "444"; + Bean2 bean2 = new Bean2(); + Copier.load(Bean1.class, Bean2.class, Copier.OPTION_SKIP_NULL_VALUE | Copier.OPTION_ALLOW_TYPE_CAST).apply(bean1, bean2); + System.out.println(JsonConvert.root().convertTo(bean2)); + Assertions.assertTrue(bean2.intval == 444); + } + + @Test + public void run16() throws Exception { + Bean3 bean1 = new Bean3(); + bean1.setSeqno(444L); + Bean4 bean2 = new Bean4(); + Copier.load(Bean3.class, Bean4.class, Copier.OPTION_SKIP_NULL_VALUE | Copier.OPTION_ALLOW_TYPE_CAST).apply(bean1, bean2); + System.out.println(JsonConvert.root().convertTo(bean2)); + Assertions.assertEquals("444", bean2.getSeqno()); + } + + @Test + public void run17() throws Exception { + Bean4 bean1 = new Bean4(); + bean1.setSeqno("444"); + Bean5 bean2 = new Bean5(); + Copier.load(Bean4.class, Bean5.class, Copier.OPTION_SKIP_NULL_VALUE | Copier.OPTION_ALLOW_TYPE_CAST).apply(bean1, bean2); + System.out.println(JsonConvert.root().convertTo(bean2)); + Assertions.assertEquals(444, bean2.getSeqno()); + } + + @Test + public void run18() throws Exception { + Bean4 bean1 = new Bean4(); + bean1.setSeqno("444"); + Bean5 bean2 = new Bean5(); + Copier.load(Bean4.class, Bean5.class, Copier.OPTION_SKIP_NULL_VALUE).apply(bean1, bean2); + System.out.println(JsonConvert.root().convertTo(bean2)); + Assertions.assertEquals(0, bean2.getSeqno()); + System.out.println("------------------------------------------"); + } + + public class Bean1 { + + public String intval; + + @Override + public String toString() { + return JsonConvert.root().convertTo(this); + } + } + + public class Bean2 { + + public int intval; + + @Override + public String toString() { + return JsonConvert.root().convertTo(this); + } + } + + public class Bean3 { + + private Long seqno; + + public Long getSeqno() { + return seqno; + } + + public void setSeqno(Long seqno) { + this.seqno = seqno; + } + + @Override + public String toString() { + return JsonConvert.root().convertTo(this); + } + } + + public class Bean4 { + + private String seqno; + + public String getSeqno() { + return seqno; + } + + public void setSeqno(String seqno) { + this.seqno = seqno; + } + + @Override + public String toString() { + return JsonConvert.root().convertTo(this); + } + } + + public class Bean5 { + + private int seqno; + + public int getSeqno() { + return seqno; + } + + public void setSeqno(int seqno) { + this.seqno = seqno; + } + + @Override + public String toString() { + return JsonConvert.root().convertTo(this); + } + } } diff --git a/src/test/java/org/redkale/test/util/TestBean.java b/src/test/java/org/redkale/test/util/TestBean.java index 8a9a6b37f..5738b21c6 100644 --- a/src/test/java/org/redkale/test/util/TestBean.java +++ b/src/test/java/org/redkale/test/util/TestBean.java @@ -21,6 +21,8 @@ public class TestBean extends TestABean implements TestInterface { private Map map; public String remark; + + private Long seqno; public String getName() { return name; @@ -46,6 +48,14 @@ public class TestBean extends TestABean implements TestInterface { this.map = map; } + public Long getSeqno() { + return seqno; + } + + public void setSeqno(Long seqno) { + this.seqno = seqno; + } + @Override public String toString() { return JsonConvert.root().convertTo(this); diff --git a/src/test/java/org/redkale/test/util/TestX2Bean.java b/src/test/java/org/redkale/test/util/TestX2Bean.java new file mode 100644 index 000000000..c07b5fd11 --- /dev/null +++ b/src/test/java/org/redkale/test/util/TestX2Bean.java @@ -0,0 +1,62 @@ +/* + * + */ +package org.redkale.test.util; + +import java.util.Map; +import org.redkale.convert.json.JsonConvert; + +/** + * + * @author zhangjx + */ +public class TestX2Bean implements TestInterface { + + private String name; + + private int id; + + private Map map; + + public int remark; + + private String seqno; + + public String getSeqno() { + return seqno; + } + + public void setSeqno(String seqno) { + this.seqno = seqno; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + + + @Override + public String toString() { + return JsonConvert.root().convertTo(this); + } +}