This commit is contained in:
@@ -104,23 +104,7 @@ public class CacheSourceService implements CacheSource, Service {
|
|||||||
File store = new File(home, "cache/" + name());
|
File store = new File(home, "cache/" + name());
|
||||||
if (!store.isFile() || !store.canRead()) return;
|
if (!store.isFile() || !store.canRead()) return;
|
||||||
LineNumberReader reader = new LineNumberReader(new FileReader(store));
|
LineNumberReader reader = new LineNumberReader(new FileReader(store));
|
||||||
final ParameterizedType storeType = new ParameterizedType() {
|
final Type storeType = TypeToken.createParameterizedType(CacheEntry.class, storeKeyType, storeValueType);
|
||||||
@Override
|
|
||||||
public Type[] getActualTypeArguments() {
|
|
||||||
return new Type[]{storeKeyType, storeValueType};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getRawType() {
|
|
||||||
return CacheEntry.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getOwnerType() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
if (line.isEmpty()) continue;
|
if (line.isEmpty()) continue;
|
||||||
@@ -148,23 +132,7 @@ public class CacheSourceService implements CacheSource, Service {
|
|||||||
store.getParentFile().mkdirs();
|
store.getParentFile().mkdirs();
|
||||||
PrintStream stream = new PrintStream(store, "UTF-8");
|
PrintStream stream = new PrintStream(store, "UTF-8");
|
||||||
Collection<CacheEntry> values = container.values();
|
Collection<CacheEntry> values = container.values();
|
||||||
final ParameterizedType storeType = new ParameterizedType() {
|
final Type storeType = TypeToken.createParameterizedType(CacheEntry.class, storeKeyType, storeValueType);;
|
||||||
@Override
|
|
||||||
public Type[] getActualTypeArguments() {
|
|
||||||
return new Type[]{storeKeyType, storeValueType};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getRawType() {
|
|
||||||
return CacheEntry.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getOwnerType() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
for (CacheEntry entry : values) {
|
for (CacheEntry entry : values) {
|
||||||
stream.println(convert.convertTo(storeType, entry));
|
stream.println(convert.convertTo(storeType, entry));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import java.beans.ConstructorProperties;
|
|||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import jdk.internal.org.objectweb.asm.*;
|
import jdk.internal.org.objectweb.asm.*;
|
||||||
import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
|
||||||
import jdk.internal.org.objectweb.asm.Type;
|
import jdk.internal.org.objectweb.asm.Type;
|
||||||
|
import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实现一个类的构造方法。 代替低效的反射实现方式。 不支持数组类
|
* 实现一个类的构造方法。 代替低效的反射实现方式。 不支持数组类
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ package org.redkale.util;
|
|||||||
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import jdk.internal.org.objectweb.asm.*;
|
||||||
|
import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 获取泛型的Type类
|
* 获取泛型的Type类
|
||||||
*
|
*
|
||||||
* @see http://www.redkale.org
|
* @see http://www.redkale.org
|
||||||
@@ -26,4 +28,52 @@ public abstract class TypeToken<T> {
|
|||||||
public final Type getType() {
|
public final Type getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Type createParameterizedType(final Class rawType, final Class... actualTypeArguments) {
|
||||||
|
ClassLoader loader = TypeToken.class.getClassLoader();
|
||||||
|
String newDynName = TypeToken.class.getName().replace('.', '/') + "_Dyn" + System.currentTimeMillis();
|
||||||
|
for (;;) {
|
||||||
|
try {
|
||||||
|
Class.forName(newDynName.replace('/', '.'));
|
||||||
|
newDynName = TypeToken.class.getName().replace('.', '/') + "_Dyn" + Math.abs(System.nanoTime());
|
||||||
|
} catch (Exception ex) { //异常说明类不存在
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ClassWriter cw = new ClassWriter(0);
|
||||||
|
FieldVisitor fv;
|
||||||
|
MethodVisitor mv;
|
||||||
|
cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, "java/lang/Object", null);
|
||||||
|
String rawTypeDesc = jdk.internal.org.objectweb.asm.Type.getDescriptor(rawType);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(rawTypeDesc.substring(0, rawTypeDesc.length() - 1)).append('<');
|
||||||
|
for (Class c : actualTypeArguments) {
|
||||||
|
sb.append(jdk.internal.org.objectweb.asm.Type.getDescriptor(c));
|
||||||
|
}
|
||||||
|
sb.append(">;");
|
||||||
|
{
|
||||||
|
fv = cw.visitField(ACC_PUBLIC, "field", rawTypeDesc, sb.toString(), null);
|
||||||
|
fv.visitEnd();
|
||||||
|
}
|
||||||
|
{//构造方法
|
||||||
|
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
|
||||||
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
|
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
|
||||||
|
mv.visitInsn(RETURN);
|
||||||
|
mv.visitMaxs(1, 1);
|
||||||
|
mv.visitEnd();
|
||||||
|
}
|
||||||
|
cw.visitEnd();
|
||||||
|
byte[] bytes = cw.toByteArray();
|
||||||
|
Class<?> newClazz = new ClassLoader(loader) {
|
||||||
|
public final Class<?> loadClass(String name, byte[] b) {
|
||||||
|
return defineClass(name, b, 0, b.length);
|
||||||
|
}
|
||||||
|
}.loadClass(newDynName.replace('/', '.'), bytes);
|
||||||
|
try {
|
||||||
|
return newClazz.getField("field").getGenericType();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user