diff --git a/src/org/redkale/util/Attribute.java b/src/org/redkale/util/Attribute.java index 869d6e198..0e35433c2 100644 --- a/src/org/redkale/util/Attribute.java +++ b/src/org/redkale/util/Attribute.java @@ -35,6 +35,8 @@ import static org.redkale.asm.Opcodes.*; *
* Attribute<Record, String> nameAction = new Attribute<Record, String>() {
*
+ * private java.lang.reflect.Type _gtype = String.class;
+ *
* @Override
* public String field() {
* return "name";
@@ -56,6 +58,11 @@ import static org.redkale.asm.Opcodes.*;
* }
*
* @Override
+ * public java.lang.reflect.Type genericType() {
+ * return _gtype;
+ * }
+ *
+ * @Override
* public Class declaringClass() {
* return Record.class;
* }
@@ -84,6 +91,15 @@ public interface Attribute {
*/
public Class extends F> type();
+ /**
+ * 返回字段的数据泛型
+ *
+ * @return 字段的数据泛型
+ */
+ default java.lang.reflect.Type genericType() {
+ return type();
+ }
+
/**
* 返回字段依附的类名
*
@@ -348,7 +364,7 @@ public interface Attribute {
* @return Attribute对象
*/
public static Attribute create(final Class clazz, String fieldalias, final Class fieldtype) {
- return create(clazz, fieldalias, fieldtype, null, null, null);
+ return create(clazz, fieldalias, fieldtype, null, (Function) null, null);
}
/**
@@ -415,12 +431,16 @@ public interface Attribute {
}
final String fieldname = fieldalias;
Class column = fieldtype;
+ java.lang.reflect.Type generictype = fieldtype;
if (tfield != null) { // public tfield
column = tfield.getType();
+ generictype = tfield.getGenericType();
} else if (tgetter != null) {
column = tgetter.getReturnType();
+ generictype = tgetter.getGenericReturnType();
} else if (tsetter != null) {
column = tsetter.getParameterTypes()[0];
+ generictype = tsetter.getGenericParameterTypes()[0];
} else if (fieldtype == null) {
throw new RuntimeException("[" + clazz + "]have no public field or setter or getter");
}
@@ -441,7 +461,11 @@ public interface Attribute {
+ fieldname.substring(fieldname.indexOf('.') + 1) + "_" + pcolumn.getSimpleName().replace("[]", "Array");
}
try {
- return (Attribute) loader.loadClass(newDynName.replace('/', '.')).getDeclaredConstructor().newInstance();
+ Attribute rs = (Attribute) loader.loadClass(newDynName.replace('/', '.')).getDeclaredConstructor().newInstance();
+ java.lang.reflect.Field _gtype = rs.getClass().getDeclaredField("_gtype");
+ _gtype.setAccessible(true);
+ _gtype.set(rs, generictype);
+ return rs;
} catch (Throwable ex) {
}
//---------------------------------------------------
@@ -449,7 +473,10 @@ public interface Attribute {
MethodVisitor mv;
cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, "Ljava/lang/Object;L" + supDynName + "<" + interDesc + columnDesc + ">;", "java/lang/Object", new String[]{supDynName});
-
+ { //_gtype
+ FieldVisitor fv = cw.visitField(ACC_PRIVATE, "_gtype", "Ljava/lang/reflect/Type;", null, null);
+ fv.visitEnd();
+ }
{ //构造方法
mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null);
mv.visitVarInsn(ALOAD, 0);
@@ -491,6 +518,14 @@ public interface Attribute {
mv.visitMaxs(1, 1);
mv.visitEnd();
}
+ { //genericType
+ mv = cw.visitMethod(ACC_PUBLIC, "genericType", "()Ljava/lang/reflect/Type;", null, null);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, newDynName, "_gtype", "Ljava/lang/reflect/Type;");
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
{ //declaringClass 方法
mv = cw.visitMethod(ACC_PUBLIC, "declaringClass", "()Ljava/lang/Class;", null, null);
mv.visitLdcInsn(Type.getType(clazz));
@@ -593,7 +628,11 @@ public interface Attribute {
}
}.loadClass(newDynName.replace('/', '.'), bytes);
try {
- return creatorClazz.getDeclaredConstructor().newInstance();
+ Attribute rs = creatorClazz.getDeclaredConstructor().newInstance();
+ java.lang.reflect.Field _gtype = rs.getClass().getDeclaredField("_gtype");
+ _gtype.setAccessible(true);
+ _gtype.set(rs, generictype);
+ return rs;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
@@ -613,6 +652,25 @@ public interface Attribute {
* @return Attribute对象
*/
public static Attribute create(final Class clazz, final String fieldname, final Class fieldtype, final Function getter, final BiConsumer setter) {
+ return create(clazz, fieldname, fieldtype, fieldtype, getter, setter);
+ }
+
+ /**
+ * 根据Class、字段名、字段类型、getter和setter方法生成 Attribute 对象。 clazz、fieldname、fieldtype都不能为null
+ *
+ * @param 依附类的类型
+ * @param 字段类型
+ * @param clazz 指定依附的类
+ * @param fieldname 字段名
+ * @param fieldtype 字段类型
+ * @param fieldGenericType 字段泛型
+ * @param getter getter方法
+ * @param setter setter方法
+ *
+ * @return Attribute对象
+ */
+ public static Attribute create(final Class clazz, final String fieldname, final Class fieldtype,
+ final java.lang.reflect.Type fieldGenericType, final Function getter, final BiConsumer setter) {
Objects.requireNonNull(clazz);
Objects.requireNonNull(fieldname);
Objects.requireNonNull(fieldtype);
@@ -622,6 +680,11 @@ public interface Attribute {
return fieldtype;
}
+ @Override
+ public java.lang.reflect.Type genericType() {
+ return fieldGenericType;
+ }
+
@Override
public Class declaringClass() {
return clazz;