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