mirror of
https://github.com/EsotericSoftware/reflectasm.git
synced 2025-02-08 18:20:29 +08:00
Added ConstructorAccess.
This commit is contained in:
parent
8aff0378d2
commit
c599cc03ab
60
src/com/esotericsoftware/reflectasm/ConstructorAccess.java
Normal file
60
src/com/esotericsoftware/reflectasm/ConstructorAccess.java
Normal file
@ -0,0 +1,60 @@
|
||||
|
||||
package com.esotericsoftware.reflectasm;
|
||||
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public abstract class ConstructorAccess<T> {
|
||||
static public <T> ConstructorAccess<T> get (Class<T> type) {
|
||||
AccessClassLoader loader = new AccessClassLoader(type.getClassLoader());
|
||||
|
||||
String className = type.getName();
|
||||
String accessClassName = className + "ConstructorAccess";
|
||||
if (accessClassName.startsWith("java.")) accessClassName = "reflectasm." + accessClassName;
|
||||
Class accessClass = null;
|
||||
try {
|
||||
accessClass = loader.loadClass(accessClassName);
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
if (accessClass == null) {
|
||||
String accessClassNameInternal = accessClassName.replace('.', '/');
|
||||
String classNameInternal = className.replace('.', '/');
|
||||
|
||||
ClassWriter cw = new ClassWriter(0);
|
||||
cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessClassNameInternal, null,
|
||||
"com/esotericsoftware/reflectasm/ConstructorAccess", null);
|
||||
MethodVisitor mv;
|
||||
{
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
|
||||
mv.visitCode();
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitMethodInsn(INVOKESPECIAL, "com/esotericsoftware/reflectasm/ConstructorAccess", "<init>", "()V");
|
||||
mv.visitInsn(RETURN);
|
||||
mv.visitMaxs(1, 1);
|
||||
mv.visitEnd();
|
||||
}
|
||||
{
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "newInstance", "()Ljava/lang/Object;", null, null);
|
||||
mv.visitCode();
|
||||
mv.visitTypeInsn(NEW, classNameInternal);
|
||||
mv.visitInsn(DUP);
|
||||
mv.visitMethodInsn(INVOKESPECIAL, classNameInternal, "<init>", "()V");
|
||||
mv.visitInsn(ARETURN);
|
||||
mv.visitMaxs(2, 1);
|
||||
mv.visitEnd();
|
||||
}
|
||||
cw.visitEnd();
|
||||
byte[] data = cw.toByteArray();
|
||||
accessClass = loader.defineClass(accessClassName, data);
|
||||
}
|
||||
try {
|
||||
return (ConstructorAccess)accessClass.newInstance();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("Error constructing field access class: " + accessClassName, ex);
|
||||
}
|
||||
}
|
||||
|
||||
abstract public T newInstance ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user