mirror of
https://github.com/EsotericSoftware/reflectasm.git
synced 2025-02-13 04:40:26 +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