Dieses Tool unterstützt das Generieren von Bytecode für
Java. Emit ist aus dem
Intersult Maven Repository zu beziehen. Wesentlicher Design-Aspekt ist das einfache Benutzen und ein schlankes Paket.
Schnelle Reflection#
Die Klasse FastMethod erzeugt einen Reflection-Code, der deutlich schneller ist, als der JVM-Code:
public class FastMethodTest {
public static final long N = 10000000000L;
@Test
public void testInvoke() throws Exception {
FastMethod fastMethod = FastMethod.create(FastMethodTest.class, "someMethod");
String result = (String)fastMethod.invoke(this);
Assert.assertEquals("test-value", result);
}
public void testFastMethod() throws Exception {
FastMethod method = FastMethod.create(FastMethodTest.class, "someMethod");
method.invoke(this);
long begin = System.nanoTime();
for (long i = 0; i < N; ++i) {
method.invoke(this);
}
long duration = System.nanoTime() - begin;
System.out.println("FastMethod: " + duration / 1000000000D + " s");
}
public void testMethod() throws Exception {
Method method = FastMethodTest.class.getDeclaredMethod("someMethod");
method.invoke(this);
long begin = System.nanoTime();
for (long i = 0; i < 10000000000L; ++i) {
method.invoke(this);
}
long duration = System.nanoTime() - begin;
System.out.println("Method: " + duration / 1000000000D + " s");
}
public String someMethod() {
return "test-value";
}
}
Interceptor#
Damit kann man Klassen wrappen und Methodenaufrufe abfangen:
public class ProxyTest extends TestCase {
public static class Test {
private String field;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
@Override
public String toString() {
return String.valueOf(field);
}
}
public static class TestInterceptor implements Interceptor {
public Object get(Object object, String name) {
System.out.println("interceptor getter: " + name);
return "interceptor value";
}
public void set(Object object, String name, Object value) {
System.out.println("interceptor setter: " + name + " = " + value);
}
}
public void testCreateProxyClass() throws Exception {
TestInterceptor testInterceptor = new TestInterceptor();
Class<? extends Test> testProxyClass = Proxy.createProxyClass(Test.class);
Test testProxy = testProxyClass.getConstructor(new Class[] {Interceptor.class}).newInstance(testInterceptor);
String text = testProxy.getField();
System.out.println(text);
testProxy.setField("set value");
}
}
Class Builder#
Damit kann man komplette Klassen dynamisch emittieren:
public class ClassBuilderTest extends TestCase {
public static class TestBase {
public String test() {
return "Test base";
}
}
public void testClassBuilder() throws InstantiationException, IllegalAccessException {
ClassBuilder<TestBase> classBuilder = new ClassBuilder<TestBase>("org.ksoft.emit.builder.Test", TestBase.class);
classBuilder.addMethod(EnumSet.of(Modifier.Public), "test", String.class).addStatement(
new Statement.Return(
new Statement.StringConstant("Test overwritten")
)
);
TestBase test = classBuilder.newInstance();
String string = test.test();
System.out.print(string);
}
}