diff --git a/android-jdk6-redkale/src/org/redkale/convert/ObjectEncoder.java b/android-jdk6-redkale/src/org/redkale/convert/ObjectEncoder.java index 079364c37..77134001b 100644 --- a/android-jdk6-redkale/src/org/redkale/convert/ObjectEncoder.java +++ b/android-jdk6-redkale/src/org/redkale/convert/ObjectEncoder.java @@ -5,7 +5,6 @@ */ package org.redkale.convert; -import java.beans.*; import org.redkale.util.Attribute; import java.lang.reflect.*; import java.util.*; @@ -242,7 +241,7 @@ public final class ObjectEncoder implements Encodeable() { * @Override + * @ConstructorParameters({"id", "name"}) * public Record create(Object... params) { * return new Record((Integer) params[0], (String) params[1]); * } * }; * } * } + * + * 或者: + * public class Record { + * + * private final int id; + * + * private String name; + * + * @ConstructorProperties({"id", "name"}) + * public Record(int id, String name) { + * this.id = id; + * this.name = name; + * } + * } * * @see http://www.redkale.org * @author zhangjx @@ -43,9 +62,17 @@ import org.objectweb.asm.Type; */ public interface Creator { + @Documented + @Target({CONSTRUCTOR, TYPE}) + @Retention(RUNTIME) + public static @interface ConstructorParameters { + + String[] value(); + } + public T create(Object... params); - public static abstract class Creators { + public abstract class Creators { @SuppressWarnings("unchecked") public static Creator create(Class clazz) { @@ -64,7 +91,7 @@ public interface Creator { if (method.getParameterTypes().length != 0) continue; if (method.getReturnType() != Creator.class) continue; try { - method.setAccessible(true); + method.setAccessible(true); return (Creator) method.invoke(null); } catch (Exception e) { throw new RuntimeException(e); @@ -91,33 +118,24 @@ public interface Creator { } } if (constructor == null) { - for (Constructor c : clazz.getConstructors()) { - if (c.getAnnotation(ConstructorProperties.class) != null) { + for (Constructor c : clazz.getDeclaredConstructors()) { + if (Modifier.isPrivate(c.getModifiers())) continue; + if (c.getAnnotation(ConstructorProperties.class) != null || c.getAnnotation(ConstructorParameters.class) != null) { constructor = c; break; } } } - if (constructor == null) throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor."); + if (constructor == null) throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation or ConstructorParameters-Annotation constructor."); //------------------------------------------------------------- ClassWriter cw = new ClassWriter(0); FieldVisitor fv; MethodVisitor mv; AnnotationVisitor av0; - cw.visit(V1_7, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, "Ljava/lang/Object;L" + supDynName + "<" + interDesc + ">;", "java/lang/Object", new String[]{supDynName}); + cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, "Ljava/lang/Object;L" + supDynName + "<" + interDesc + ">;", "java/lang/Object", new String[]{supDynName}); {//构造方法 mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - ConstructorProperties cps = constructor.getAnnotation(ConstructorProperties.class); - if (cps != null) { - av0 = mv.visitAnnotation(Type.getDescriptor(ConstructorProperties.class), true); - AnnotationVisitor av1 = av0.visitArray("value"); - for (String n : cps.value()) { - av1.visit(null, n); - } - av1.visitEnd(); - av0.visitEnd(); - } mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); mv.visitInsn(RETURN); @@ -126,6 +144,18 @@ public interface Creator { } {//create 方法 mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "create", "([Ljava/lang/Object;)L" + interName + ";", null, null); + ConstructorProperties cps = constructor.getAnnotation(ConstructorProperties.class); + ConstructorParameters cts = constructor.getAnnotation(ConstructorParameters.class); + final String[] cparams = cps == null ? (cts == null ? null : cts.value()) : cps.value(); + if (cparams != null) { + av0 = mv.visitAnnotation(Type.getDescriptor(ConstructorParameters.class), true); + AnnotationVisitor av1 = av0.visitArray("value"); + for (String n : cps.value()) { + av1.visit(null, n); + } + av1.visitEnd(); + av0.visitEnd(); + } mv.visitTypeInsn(NEW, interName); mv.visitInsn(DUP); //---------------------------------------