优化Creator
This commit is contained in:
@@ -72,262 +72,6 @@ import org.redkale.asm.Type;
|
||||
*/
|
||||
public interface Creator<T> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static class CreatorInner {
|
||||
|
||||
static final Logger logger = Logger.getLogger(Creator.class.getSimpleName());
|
||||
|
||||
static final Map<Class, Creator> creatorCacheMap = new HashMap<>();
|
||||
|
||||
static final Map<Class, IntFunction> arrayCacheMap = new ConcurrentHashMap<>();
|
||||
|
||||
static {
|
||||
creatorCacheMap.put(Object.class, p -> new Object());
|
||||
creatorCacheMap.put(ArrayList.class, p -> new ArrayList<>());
|
||||
creatorCacheMap.put(HashMap.class, p -> new HashMap<>());
|
||||
creatorCacheMap.put(HashSet.class, p -> new HashSet<>());
|
||||
creatorCacheMap.put(Stream.class, p -> new ArrayList<>().stream());
|
||||
creatorCacheMap.put(ConcurrentHashMap.class, p -> new ConcurrentHashMap<>());
|
||||
creatorCacheMap.put(CompletableFuture.class, p -> new CompletableFuture<>());
|
||||
creatorCacheMap.put(CompletionStage.class, p -> new CompletableFuture<>());
|
||||
creatorCacheMap.put(Map.Entry.class, new Creator<Map.Entry>() {
|
||||
@Override
|
||||
@ConstructorParameters({"key", "value"})
|
||||
public Map.Entry create(Object... params) {
|
||||
return new AbstractMap.SimpleEntry(params[0], params[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class[] paramTypes() {
|
||||
return new Class[]{Object.class, Object.class};
|
||||
}
|
||||
});
|
||||
creatorCacheMap.put(AbstractMap.SimpleEntry.class, new Creator<AbstractMap.SimpleEntry>() {
|
||||
@Override
|
||||
@ConstructorParameters({"key", "value"})
|
||||
public AbstractMap.SimpleEntry create(Object... params) {
|
||||
return new AbstractMap.SimpleEntry(params[0], params[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class[] paramTypes() {
|
||||
return new Class[]{Object.class, Object.class};
|
||||
}
|
||||
});
|
||||
creatorCacheMap.put(AnyValue.DefaultAnyValue.class, p -> new AnyValue.DefaultAnyValue());
|
||||
creatorCacheMap.put(AnyValue.class, p -> new AnyValue.DefaultAnyValue());
|
||||
|
||||
arrayCacheMap.put(int.class, t -> new int[t]);
|
||||
arrayCacheMap.put(byte.class, t -> new byte[t]);
|
||||
arrayCacheMap.put(long.class, t -> new long[t]);
|
||||
arrayCacheMap.put(String.class, t -> new String[t]);
|
||||
arrayCacheMap.put(Object.class, t -> new Object[t]);
|
||||
arrayCacheMap.put(boolean.class, t -> new boolean[t]);
|
||||
arrayCacheMap.put(short.class, t -> new short[t]);
|
||||
arrayCacheMap.put(char.class, t -> new char[t]);
|
||||
arrayCacheMap.put(float.class, t -> new float[t]);
|
||||
arrayCacheMap.put(double.class, t -> new double[t]);
|
||||
}
|
||||
|
||||
static class SimpleClassVisitor extends ClassVisitor {
|
||||
|
||||
private final String constructorDesc;
|
||||
|
||||
private final List<String> fieldnames;
|
||||
|
||||
private boolean started;
|
||||
|
||||
public SimpleClassVisitor(int api, List<String> fieldnames, String constructorDesc) {
|
||||
super(api);
|
||||
this.fieldnames = fieldnames;
|
||||
this.constructorDesc = constructorDesc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
if (java.lang.reflect.Modifier.isStatic(access) || !"<init>".equals(name)) {
|
||||
return null;
|
||||
}
|
||||
if (constructorDesc != null && !constructorDesc.equals(desc)) {
|
||||
return null;
|
||||
}
|
||||
if (this.started) {
|
||||
return null;
|
||||
}
|
||||
this.started = true;
|
||||
//返回的List中参数列表可能会比方法参数量多,因为方法内的临时变量也会存入list中, 所以需要list的元素集合比方法的参数多
|
||||
return new MethodVisitor(Opcodes.ASM6) {
|
||||
@Override
|
||||
public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) {
|
||||
if (index < 1) {
|
||||
return;
|
||||
}
|
||||
int size = fieldnames.size();
|
||||
//index不会按顺序执行的
|
||||
if (index > size) {
|
||||
for (int i = size; i < index; i++) {
|
||||
fieldnames.add(" ");
|
||||
}
|
||||
fieldnames.set(index - 1, name);
|
||||
}
|
||||
fieldnames.set(index - 1, name);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static SimpleEntry<String, Class>[] getConstructorField(Class clazz, int paramcount, String constructorDesc) {
|
||||
String n = clazz.getName();
|
||||
InputStream in = clazz.getResourceAsStream(n.substring(n.lastIndexOf('.') + 1) + ".class");
|
||||
if (in == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
|
||||
byte[] bytes = new byte[1024];
|
||||
int pos;
|
||||
try {
|
||||
while ((pos = in.read(bytes)) != -1) {
|
||||
out.write(bytes, 0, pos);
|
||||
}
|
||||
in.close();
|
||||
} catch (IOException io) {
|
||||
return null;
|
||||
}
|
||||
final List<String> fieldnames = new ArrayList<>();
|
||||
new ClassReader(out.toByteArray()).accept(new SimpleClassVisitor(Opcodes.ASM6, fieldnames, constructorDesc), 0);
|
||||
while (fieldnames.remove(" ")); //删掉空元素
|
||||
if (fieldnames.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (paramcount == fieldnames.size()) {
|
||||
return getConstructorField(clazz, paramcount, fieldnames.toArray(new String[fieldnames.size()]));
|
||||
} else {
|
||||
String[] fs = new String[paramcount];
|
||||
for (int i = 0; i < fs.length; i++) {
|
||||
fs[i] = fieldnames.get(i);
|
||||
}
|
||||
return getConstructorField(clazz, paramcount, fs);
|
||||
}
|
||||
}
|
||||
|
||||
public static SimpleEntry<String, Class>[] getConstructorField(Class clazz, int paramcount, String[] names) {
|
||||
SimpleEntry<String, Class>[] se = new SimpleEntry[names.length];
|
||||
for (int i = 0; i < names.length; i++) { //查询参数名对应的Field
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(names[i]);
|
||||
se[i] = new SimpleEntry<>(field.getName(), field.getType());
|
||||
} catch (NoSuchFieldException fe) {
|
||||
Class cz = clazz;
|
||||
Field field = null;
|
||||
while ((cz = cz.getSuperclass()) != Object.class) {
|
||||
try {
|
||||
field = cz.getDeclaredField(names[i]);
|
||||
break;
|
||||
} catch (NoSuchFieldException nsfe) {
|
||||
}
|
||||
}
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
se[i] = new SimpleEntry<>(field.getName(), field.getType());
|
||||
} catch (Exception e) {
|
||||
if (logger.isLoggable(Level.FINE)) {
|
||||
logger.log(Level.FINE, clazz + " getConstructorField error", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return se;
|
||||
}
|
||||
|
||||
public static SimpleEntry<String, Class>[] getConstructorField(Class clazz, int paramcount, Parameter[] params) {
|
||||
SimpleEntry<String, Class>[] se = new SimpleEntry[params.length];
|
||||
for (int i = 0; i < params.length; i++) { //查询参数名对应的Field
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(params[i].getName());
|
||||
se[i] = new SimpleEntry<>(field.getName(), field.getType());
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return se;
|
||||
}
|
||||
|
||||
static class TypeArrayIntFunction<T> implements IntFunction<T[]> {
|
||||
|
||||
private final Class<T> type;
|
||||
|
||||
public TypeArrayIntFunction(Class<T> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T[] apply(int value) {
|
||||
return (T[]) Array.newInstance(type, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static <T> IntFunction<T[]> createArrayFunction(final Class<T> clazz) {
|
||||
final String interName = clazz.getName().replace('.', '/');
|
||||
final String interDesc = Type.getDescriptor(clazz);
|
||||
final ClassLoader loader = clazz.getClassLoader();
|
||||
final String newDynName = "org/redkaledyn/creator/_DynArrayFunction__" + clazz.getName().replace('.', '_').replace('$', '_');
|
||||
try {
|
||||
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
|
||||
return (IntFunction) (clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz).getDeclaredConstructor().newInstance();
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
MethodVisitor mv;
|
||||
cw.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, "Ljava/lang/Object;Ljava/util/function/IntFunction<[" + interDesc + ">;", "java/lang/Object", new String[]{"java/util/function/IntFunction"});
|
||||
|
||||
{//IntFunction自身的构造方法
|
||||
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();
|
||||
}
|
||||
{//apply 方法
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "apply", "(I)[" + interDesc, null, null);
|
||||
mv.visitVarInsn(ILOAD, 1);
|
||||
mv.visitTypeInsn(ANEWARRAY, interName);
|
||||
mv.visitInsn(ARETURN);
|
||||
mv.visitMaxs(1, 2);
|
||||
mv.visitEnd();
|
||||
}
|
||||
{ //虚拟 apply 方法
|
||||
mv = cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "apply", "(I)Ljava/lang/Object;", null, null);
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitVarInsn(ILOAD, 1);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "apply", "(I)[" + interDesc, false);
|
||||
mv.visitInsn(ARETURN);
|
||||
mv.visitMaxs(2, 2);
|
||||
mv.visitEnd();
|
||||
}
|
||||
cw.visitEnd();
|
||||
final byte[] bytes = cw.toByteArray();
|
||||
try {
|
||||
Class<?> resultClazz = new ClassLoader(loader) {
|
||||
public final Class<?> loadClass(String name, byte[] b) {
|
||||
return defineClass(name, b, 0, b.length);
|
||||
}
|
||||
}.loadClass(newDynName.replace('/', '.'), bytes);
|
||||
RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, resultClazz);
|
||||
RedkaleClassLoader.putReflectionDeclaredConstructors(resultClazz, newDynName.replace('/', '.'));
|
||||
return (IntFunction<T[]>) resultClazz.getDeclaredConstructor().newInstance();
|
||||
} catch (Exception ex) {
|
||||
//ex.printStackTrace(); //一般不会发生
|
||||
//return t -> (T[]) Array.newInstance(clazz, t);
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建对象
|
||||
*
|
||||
@@ -340,6 +84,7 @@ public interface Creator<T> {
|
||||
/**
|
||||
* 参数类型数组
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @return 参数类型数组
|
||||
*/
|
||||
default Class[] paramTypes() {
|
||||
@@ -355,7 +100,7 @@ public interface Creator<T> {
|
||||
* @return IntFunction
|
||||
*/
|
||||
public static <T> IntFunction<T[]> arrayFunction(final Class<T> type) {
|
||||
return CreatorInner.arrayCacheMap.computeIfAbsent(type, t -> CreatorInner.createArrayFunction(t));
|
||||
return CreatorInner.arrayCacheMap.computeIfAbsent(type, CreatorInner::createArrayFunction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -822,4 +567,246 @@ public interface Creator<T> {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static class CreatorInner {
|
||||
|
||||
static final Logger logger = Logger.getLogger(Creator.class.getSimpleName());
|
||||
|
||||
static final Map<Class, Creator> creatorCacheMap = new HashMap<>();
|
||||
|
||||
static final Map<Class, IntFunction> arrayCacheMap = new ConcurrentHashMap<>();
|
||||
|
||||
static {
|
||||
creatorCacheMap.put(Object.class, p -> new Object());
|
||||
creatorCacheMap.put(ArrayList.class, p -> new ArrayList<>());
|
||||
creatorCacheMap.put(HashMap.class, p -> new HashMap<>());
|
||||
creatorCacheMap.put(HashSet.class, p -> new HashSet<>());
|
||||
creatorCacheMap.put(Stream.class, p -> new ArrayList<>().stream());
|
||||
creatorCacheMap.put(ConcurrentHashMap.class, p -> new ConcurrentHashMap<>());
|
||||
creatorCacheMap.put(CompletableFuture.class, p -> new CompletableFuture<>());
|
||||
creatorCacheMap.put(CompletionStage.class, p -> new CompletableFuture<>());
|
||||
creatorCacheMap.put(Map.Entry.class, new Creator<Map.Entry>() {
|
||||
@Override
|
||||
@ConstructorParameters({"key", "value"})
|
||||
public Map.Entry create(Object... params) {
|
||||
return new AbstractMap.SimpleEntry(params[0], params[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class[] paramTypes() {
|
||||
return new Class[]{Object.class, Object.class};
|
||||
}
|
||||
});
|
||||
creatorCacheMap.put(AbstractMap.SimpleEntry.class, new Creator<AbstractMap.SimpleEntry>() {
|
||||
@Override
|
||||
@ConstructorParameters({"key", "value"})
|
||||
public AbstractMap.SimpleEntry create(Object... params) {
|
||||
return new AbstractMap.SimpleEntry(params[0], params[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class[] paramTypes() {
|
||||
return new Class[]{Object.class, Object.class};
|
||||
}
|
||||
});
|
||||
creatorCacheMap.put(AnyValue.DefaultAnyValue.class, p -> new AnyValue.DefaultAnyValue());
|
||||
creatorCacheMap.put(AnyValue.class, p -> new AnyValue.DefaultAnyValue());
|
||||
|
||||
arrayCacheMap.put(int.class, t -> new int[t]);
|
||||
arrayCacheMap.put(byte.class, t -> new byte[t]);
|
||||
arrayCacheMap.put(long.class, t -> new long[t]);
|
||||
arrayCacheMap.put(String.class, t -> new String[t]);
|
||||
arrayCacheMap.put(Object.class, t -> new Object[t]);
|
||||
arrayCacheMap.put(boolean.class, t -> new boolean[t]);
|
||||
arrayCacheMap.put(short.class, t -> new short[t]);
|
||||
arrayCacheMap.put(char.class, t -> new char[t]);
|
||||
arrayCacheMap.put(float.class, t -> new float[t]);
|
||||
arrayCacheMap.put(double.class, t -> new double[t]);
|
||||
}
|
||||
|
||||
static class SimpleClassVisitor extends ClassVisitor {
|
||||
|
||||
private final String constructorDesc;
|
||||
|
||||
private final List<String> fieldNames;
|
||||
|
||||
private boolean started;
|
||||
|
||||
public SimpleClassVisitor(int api, List<String> fieldNames, String constructorDesc) {
|
||||
super(api);
|
||||
this.fieldNames = fieldNames;
|
||||
this.constructorDesc = constructorDesc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
if (java.lang.reflect.Modifier.isStatic(access) || !"<init>".equals(name)) {
|
||||
return null;
|
||||
}
|
||||
if (constructorDesc != null && !constructorDesc.equals(desc)) {
|
||||
return null;
|
||||
}
|
||||
if (this.started) {
|
||||
return null;
|
||||
}
|
||||
this.started = true;
|
||||
//返回的List中参数列表可能会比方法参数量多,因为方法内的临时变量也会存入list中, 所以需要list的元素集合比方法的参数多
|
||||
return new MethodVisitor(Opcodes.ASM6) {
|
||||
@Override
|
||||
public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) {
|
||||
if (index < 1) {
|
||||
return;
|
||||
}
|
||||
int size = fieldNames.size();
|
||||
//index不会按顺序执行的
|
||||
if (index > size) {
|
||||
for (int i = size; i < index; i++) {
|
||||
fieldNames.add(" ");
|
||||
}
|
||||
fieldNames.set(index - 1, name);
|
||||
}
|
||||
fieldNames.set(index - 1, name);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static SimpleEntry<String, Class>[] getConstructorField(Class clazz, int paramCount, String constructorDesc) {
|
||||
String n = clazz.getName();
|
||||
InputStream in = clazz.getResourceAsStream(n.substring(n.lastIndexOf('.') + 1) + ".class");
|
||||
if (in == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
|
||||
byte[] bytes = new byte[1024];
|
||||
int pos;
|
||||
try {
|
||||
while ((pos = in.read(bytes)) != -1) {
|
||||
out.write(bytes, 0, pos);
|
||||
}
|
||||
in.close();
|
||||
} catch (IOException io) {
|
||||
return null;
|
||||
}
|
||||
final List<String> fieldNames = new ArrayList<>();
|
||||
new ClassReader(out.toByteArray()).accept(new SimpleClassVisitor(Opcodes.ASM6, fieldNames, constructorDesc), 0);
|
||||
while (fieldNames.remove(" ")); //删掉空元素
|
||||
if (fieldNames.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (paramCount == fieldNames.size()) {
|
||||
return getConstructorField(clazz, paramCount, fieldNames.toArray(new String[fieldNames.size()]));
|
||||
} else {
|
||||
String[] fs = new String[paramCount];
|
||||
for (int i = 0; i < fs.length; i++) {
|
||||
fs[i] = fieldNames.get(i);
|
||||
}
|
||||
return getConstructorField(clazz, paramCount, fs);
|
||||
}
|
||||
}
|
||||
|
||||
public static SimpleEntry<String, Class>[] getConstructorField(Class clazz, int paramCount, String[] names) {
|
||||
SimpleEntry<String, Class>[] se = new SimpleEntry[names.length];
|
||||
for (int i = 0; i < names.length; i++) { //查询参数名对应的Field
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(names[i]);
|
||||
se[i] = new SimpleEntry<>(field.getName(), field.getType());
|
||||
} catch (NoSuchFieldException fe) {
|
||||
Class cz = clazz;
|
||||
Field field = null;
|
||||
while ((cz = cz.getSuperclass()) != Object.class) {
|
||||
try {
|
||||
field = cz.getDeclaredField(names[i]);
|
||||
break;
|
||||
} catch (NoSuchFieldException nsfe) {
|
||||
}
|
||||
}
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
se[i] = new SimpleEntry<>(field.getName(), field.getType());
|
||||
} catch (Exception e) {
|
||||
if (logger.isLoggable(Level.FINE)) {
|
||||
logger.log(Level.FINE, clazz + " getConstructorField error", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return se;
|
||||
}
|
||||
|
||||
public static SimpleEntry<String, Class>[] getConstructorField(Class clazz, int paramCount, Parameter[] params) {
|
||||
SimpleEntry<String, Class>[] se = new SimpleEntry[params.length];
|
||||
for (int i = 0; i < params.length; i++) { //查询参数名对应的Field
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(params[i].getName());
|
||||
se[i] = new SimpleEntry<>(field.getName(), field.getType());
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return se;
|
||||
}
|
||||
|
||||
public static <T> IntFunction<T[]> createArrayFunction(final Class<T> clazz) {
|
||||
final String interName = clazz.getName().replace('.', '/');
|
||||
final String interDesc = Type.getDescriptor(clazz);
|
||||
final ClassLoader loader = clazz.getClassLoader();
|
||||
final String newDynName = "org/redkaledyn/creator/_DynArrayFunction__" + clazz.getName().replace('.', '_').replace('$', '_');
|
||||
try {
|
||||
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
|
||||
return (IntFunction) (clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz).getDeclaredConstructor().newInstance();
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
MethodVisitor mv;
|
||||
cw.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, "Ljava/lang/Object;Ljava/util/function/IntFunction<[" + interDesc + ">;", "java/lang/Object", new String[]{"java/util/function/IntFunction"});
|
||||
|
||||
{//IntFunction自身的构造方法
|
||||
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();
|
||||
}
|
||||
{//apply 方法
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "apply", "(I)[" + interDesc, null, null);
|
||||
mv.visitVarInsn(ILOAD, 1);
|
||||
mv.visitTypeInsn(ANEWARRAY, interName);
|
||||
mv.visitInsn(ARETURN);
|
||||
mv.visitMaxs(1, 2);
|
||||
mv.visitEnd();
|
||||
}
|
||||
{ //虚拟 apply 方法
|
||||
mv = cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "apply", "(I)Ljava/lang/Object;", null, null);
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitVarInsn(ILOAD, 1);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "apply", "(I)[" + interDesc, false);
|
||||
mv.visitInsn(ARETURN);
|
||||
mv.visitMaxs(2, 2);
|
||||
mv.visitEnd();
|
||||
}
|
||||
cw.visitEnd();
|
||||
final byte[] bytes = cw.toByteArray();
|
||||
try {
|
||||
Class<?> resultClazz = new ClassLoader(loader) {
|
||||
public final Class<?> loadClass(String name, byte[] b) {
|
||||
return defineClass(name, b, 0, b.length);
|
||||
}
|
||||
}.loadClass(newDynName.replace('/', '.'), bytes);
|
||||
RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, resultClazz);
|
||||
RedkaleClassLoader.putReflectionDeclaredConstructors(resultClazz, newDynName.replace('/', '.'));
|
||||
return (IntFunction<T[]>) resultClazz.getDeclaredConstructor().newInstance();
|
||||
} catch (Exception ex) {
|
||||
//ex.printStackTrace(); //一般不会发生
|
||||
//return t -> (T[]) Array.newInstance(clazz, t);
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user