This commit is contained in:
wentch
2015-12-18 11:23:09 +08:00
parent c2318297fa
commit 6b5eb3d545
3 changed files with 54 additions and 36 deletions

View File

@@ -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));
} }

View File

@@ -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.*;
/** /**
* 实现一个类的构造方法。 代替低效的反射实现方式。 不支持数组类 * 实现一个类的构造方法。 代替低效的反射实现方式。 不支持数组类

View File

@@ -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);
}
}
} }