Attribute增加genericType方法

This commit is contained in:
Redkale
2018-11-28 09:12:58 +08:00
parent d07c55b831
commit 9493aa43a7

View File

@@ -35,6 +35,8 @@ import static org.redkale.asm.Opcodes.*;
* <blockquote><pre> * <blockquote><pre>
* Attribute&lt;Record, String&gt; nameAction = new Attribute&lt;Record, String&gt;() { * Attribute&lt;Record, String&gt; nameAction = new Attribute&lt;Record, String&gt;() {
* *
* private java.lang.reflect.Type _gtype = String.class;
*
* &#64;Override * &#64;Override
* public String field() { * public String field() {
* return "name"; * return "name";
@@ -56,6 +58,11 @@ import static org.redkale.asm.Opcodes.*;
* } * }
* *
* &#64;Override * &#64;Override
* public java.lang.reflect.Type genericType() {
* return _gtype;
* }
*
* &#64;Override
* public Class declaringClass() { * public Class declaringClass() {
* return Record.class; * return Record.class;
* } * }
@@ -84,6 +91,15 @@ public interface Attribute<T, F> {
*/ */
public Class<? extends F> type(); public Class<? extends F> type();
/**
* 返回字段的数据泛型
*
* @return 字段的数据泛型
*/
default java.lang.reflect.Type genericType() {
return type();
}
/** /**
* 返回字段依附的类名 * 返回字段依附的类名
* *
@@ -348,7 +364,7 @@ public interface Attribute<T, F> {
* @return Attribute对象 * @return Attribute对象
*/ */
public static <T, F> Attribute<T, F> create(final Class<T> clazz, String fieldalias, final Class<F> fieldtype) { public static <T, F> Attribute<T, F> create(final Class<T> clazz, String fieldalias, final Class<F> 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<T, F> {
} }
final String fieldname = fieldalias; final String fieldname = fieldalias;
Class column = fieldtype; Class column = fieldtype;
java.lang.reflect.Type generictype = fieldtype;
if (tfield != null) { // public tfield if (tfield != null) { // public tfield
column = tfield.getType(); column = tfield.getType();
generictype = tfield.getGenericType();
} else if (tgetter != null) { } else if (tgetter != null) {
column = tgetter.getReturnType(); column = tgetter.getReturnType();
generictype = tgetter.getGenericReturnType();
} else if (tsetter != null) { } else if (tsetter != null) {
column = tsetter.getParameterTypes()[0]; column = tsetter.getParameterTypes()[0];
generictype = tsetter.getGenericParameterTypes()[0];
} else if (fieldtype == null) { } else if (fieldtype == null) {
throw new RuntimeException("[" + clazz + "]have no public field or setter or getter"); throw new RuntimeException("[" + clazz + "]have no public field or setter or getter");
} }
@@ -441,7 +461,11 @@ public interface Attribute<T, F> {
+ fieldname.substring(fieldname.indexOf('.') + 1) + "_" + pcolumn.getSimpleName().replace("[]", "Array"); + fieldname.substring(fieldname.indexOf('.') + 1) + "_" + pcolumn.getSimpleName().replace("[]", "Array");
} }
try { 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) { } catch (Throwable ex) {
} }
//--------------------------------------------------- //---------------------------------------------------
@@ -449,7 +473,10 @@ public interface Attribute<T, F> {
MethodVisitor mv; 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}); 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, "<init>", "()V", null, null); mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
@@ -491,6 +518,14 @@ public interface Attribute<T, F> {
mv.visitMaxs(1, 1); mv.visitMaxs(1, 1);
mv.visitEnd(); 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 方法 { //declaringClass 方法
mv = cw.visitMethod(ACC_PUBLIC, "declaringClass", "()Ljava/lang/Class;", null, null); mv = cw.visitMethod(ACC_PUBLIC, "declaringClass", "()Ljava/lang/Class;", null, null);
mv.visitLdcInsn(Type.getType(clazz)); mv.visitLdcInsn(Type.getType(clazz));
@@ -593,7 +628,11 @@ public interface Attribute<T, F> {
} }
}.loadClass(newDynName.replace('/', '.'), bytes); }.loadClass(newDynName.replace('/', '.'), bytes);
try { 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) { } catch (Exception ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
@@ -613,6 +652,25 @@ public interface Attribute<T, F> {
* @return Attribute对象 * @return Attribute对象
*/ */
public static <T, F> Attribute<T, F> create(final Class<T> clazz, final String fieldname, final Class<F> fieldtype, final Function<T, F> getter, final BiConsumer<T, F> setter) { public static <T, F> Attribute<T, F> create(final Class<T> clazz, final String fieldname, final Class<F> fieldtype, final Function<T, F> getter, final BiConsumer<T, F> setter) {
return create(clazz, fieldname, fieldtype, fieldtype, getter, setter);
}
/**
* 根据Class、字段名、字段类型、getter和setter方法生成 Attribute 对象。 clazz、fieldname、fieldtype都不能为null
*
* @param <T> 依附类的类型
* @param <F> 字段类型
* @param clazz 指定依附的类
* @param fieldname 字段名
* @param fieldtype 字段类型
* @param fieldGenericType 字段泛型
* @param getter getter方法
* @param setter setter方法
*
* @return Attribute对象
*/
public static <T, F> Attribute<T, F> create(final Class<T> clazz, final String fieldname, final Class<F> fieldtype,
final java.lang.reflect.Type fieldGenericType, final Function<T, F> getter, final BiConsumer<T, F> setter) {
Objects.requireNonNull(clazz); Objects.requireNonNull(clazz);
Objects.requireNonNull(fieldname); Objects.requireNonNull(fieldname);
Objects.requireNonNull(fieldtype); Objects.requireNonNull(fieldtype);
@@ -622,6 +680,11 @@ public interface Attribute<T, F> {
return fieldtype; return fieldtype;
} }
@Override
public java.lang.reflect.Type genericType() {
return fieldGenericType;
}
@Override @Override
public Class<T> declaringClass() { public Class<T> declaringClass() {
return clazz; return clazz;